All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/26] linux-user update
@ 2016-09-22 12:13 riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 01/26] linux-user: Fix handling of iovec counts riku.voipio
                   ` (27 more replies)
  0 siblings, 28 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Riku Voipio

From: Riku Voipio <riku.voipio@linaro.org>

The following changes since commit a008535b9fa396226ff9cf78b8ac5f3584bda58e:

  build-sys: fix make install regression (2016-09-20 11:32:43 +0100)

are available in the git repository at:

  git://git.linaro.org/people/riku.voipio/qemu.git tags/pull-linux-user-20160915

for you to fetch changes up to 5457dc9e37fe0a29989bd64306c63941074864ce:

  linux-user: fix TARGET_NR_select (2016-09-22 07:24:21 +0300)

----------------------------------------------------------------
linux-user changes since 2.7 release

----------------------------------------------------------------
Laurent Vivier (1):
      linux-user: fix TARGET_NR_select

Michael Walle (1):
      linux-user: ppc64: set MSR_CM bit for BookE 2.06 MMU

Peter Maydell (23):
      linux-user: Fix handling of iovec counts
      linux-user: Fix errno for sendrecvmsg with large iovec length
      linux-user: Allow bad msg_name for recvfrom on connected socket
      linux-user: Implement FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls
      linux-user: Use direct syscall for utimensat
      linux-user: Check for bad event numbers in epoll_wait
      linux-user: Range check the nfds argument to ppoll syscall
      linux-user: report signals being taken in strace output
      linux-user: Pass missing MAP_ANONYMOUS to target_mmap() call
      linux-user: Check lock_user() return value for NULL
      linux-user: Fix incorrect use of host errno in do_ioctl_dm()
      linux-user: Fix error handling in flatload.c target_pread()
      linux-user: Check dump_write() return in elf_core_dump()
      linux-user: Use glib malloc functions in load_symbols()
      linux-user: Use correct target SHMLBA in shmat()
      linux-user: Recheck for pending synchronous signals too
      linux-user: Pass si_type information to queue_signal() explicitly
      linux-user: SIGSEGV on signal entry need not be fatal
      linux-user: ARM: Give SIGSEGV if signal frame setup fails
      linux-user: SIGSEGV from sigreturn need not be fatal
      linux-user: Implement force_sigsegv() via force_sig()
      linux-user: Remove unnecessary nptl_flags variable from do_fork()
      linux-user: Sanity check clone flags

Timothy E Baldwin (1):
      linux-user: Fix incorrect offset of tuc_stack in ARM do_sigframe_return_v2

 linux-user/arm/target_syscall.h        |   8 ++
 linux-user/elfload.c                   |  20 ++---
 linux-user/flatload.c                  |   6 ++
 linux-user/i386/target_syscall.h       |   1 +
 linux-user/ioctls.h                    |   3 +
 linux-user/m68k/target_syscall.h       |   2 +
 linux-user/main.c                      | 129 +++++++++++++++---------------
 linux-user/microblaze/target_syscall.h |   2 +
 linux-user/mips/target_syscall.h       |   7 ++
 linux-user/mips64/target_syscall.h     |   7 ++
 linux-user/openrisc/syscall_nr.h       |   2 -
 linux-user/ppc/target_syscall.h        |   1 +
 linux-user/qemu.h                      |  13 ++-
 linux-user/sh4/syscall_nr.h            |   2 +-
 linux-user/sh4/target_syscall.h        |   7 ++
 linux-user/signal.c                    | 211 ++++++++++++++++++++++++++++++-------------------
 linux-user/sparc/target_syscall.h      |  16 ++++
 linux-user/strace.c                    | 106 +++++++++++++++++++++++++
 linux-user/syscall.c                   | 241 +++++++++++++++++++++++++++++++++++++++++++-------------
 linux-user/syscall_defs.h              |   9 +++
 linux-user/tilegx/syscall_nr.h         |   1 -
 21 files changed, 581 insertions(+), 213 deletions(-)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 01/26] linux-user: Fix handling of iovec counts
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 02/26] linux-user: Fix errno for sendrecvmsg with large iovec length riku.voipio
                   ` (26 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

In the kernel the length of an iovec is generally handled as
an unsigned long, not an integer; fix the parameter to
lock_iovec() accordingly.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ca06943..71f40e3 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3119,7 +3119,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
 }
 
 static struct iovec *lock_iovec(int type, abi_ulong target_addr,
-                                int count, int copy)
+                                abi_ulong count, int copy)
 {
     struct target_iovec *target_vec;
     struct iovec *vec;
@@ -3132,7 +3132,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
         errno = 0;
         return NULL;
     }
-    if (count < 0 || count > IOV_MAX) {
+    if (count > IOV_MAX) {
         errno = EINVAL;
         return NULL;
     }
@@ -3207,7 +3207,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
 }
 
 static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
-                         int count, int copy)
+                         abi_ulong count, int copy)
 {
     struct target_iovec *target_vec;
     int i;
@@ -3462,7 +3462,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
 {
     abi_long ret, len;
     struct msghdr msg;
-    int count;
+    abi_ulong count;
     struct iovec *vec;
     abi_ulong target_vec;
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 02/26] linux-user: Fix errno for sendrecvmsg with large iovec length
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 01/26] linux-user: Fix handling of iovec counts riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 03/26] linux-user: Allow bad msg_name for recvfrom on connected socket riku.voipio
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

The sendmsg and recvmsg syscalls use a different errno to indicate
an overlarge iovec length from readv and writev. Handle this
special case in do_sendrcvmsg_locked() to avoid getting the
default errno returned by lock_iovec().

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 71f40e3..9d18326 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3485,6 +3485,15 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
 
     count = tswapal(msgp->msg_iovlen);
     target_vec = tswapal(msgp->msg_iov);
+
+    if (count > IOV_MAX) {
+        /* sendrcvmsg returns a different errno for this condition than
+         * readv/writev, so we must catch it here before lock_iovec() does.
+         */
+        ret = -TARGET_EMSGSIZE;
+        goto out2;
+    }
+
     vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE,
                      target_vec, count, send);
     if (vec == NULL) {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 03/26] linux-user: Allow bad msg_name for recvfrom on connected socket
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 01/26] linux-user: Fix handling of iovec counts riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 02/26] linux-user: Fix errno for sendrecvmsg with large iovec length riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 04/26] linux-user: Implement FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls riku.voipio
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

The POSIX standard mandates that for a connected socket recvfrom()
must ignore the msg_name and msg_namelen fields. This is awkward
for QEMU because we will attempt to copy them from guest address
space. Handle this by not immediately returning a TARGET_EFAULT
if the copy failed, but instead passing a known-bad address
to the host kernel, which can then return EFAULT or ignore the
value appropriately.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9d18326..51f558d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3472,7 +3472,14 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
         ret = target_to_host_sockaddr(fd, msg.msg_name,
                                       tswapal(msgp->msg_name),
                                       msg.msg_namelen);
-        if (ret) {
+        if (ret == -TARGET_EFAULT) {
+            /* For connected sockets msg_name and msg_namelen must
+             * be ignored, so returning EFAULT immediately is wrong.
+             * Instead, pass a bad msg_name to the host kernel, and
+             * let it decide whether to return EFAULT or not.
+             */
+            msg.msg_name = (void *)-1;
+        } else if (ret) {
             goto out2;
         }
     } else {
@@ -3534,7 +3541,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp,
             }
             if (!is_error(ret)) {
                 msgp->msg_namelen = tswap32(msg.msg_namelen);
-                if (msg.msg_name != NULL) {
+                if (msg.msg_name != NULL && msg.msg_name != (void *)-1) {
                     ret = host_to_target_sockaddr(tswapal(msgp->msg_name),
                                     msg.msg_name, msg.msg_namelen);
                     if (ret) {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 04/26] linux-user: Implement FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (2 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 03/26] linux-user: Allow bad msg_name for recvfrom on connected socket riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 05/26] linux-user: Use direct syscall for utimensat riku.voipio
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

Implement the FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls, as used
by chattr.

Note that the type information encoded in these ioctl numbers
is at odds with the actual type the kernel accesses, as discussed
in http://thread.gmane.org/gmane.linux.file-systems/80164.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/ioctls.h       | 3 +++
 linux-user/syscall_defs.h | 6 ++++++
 2 files changed, 9 insertions(+)

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 7e2c133..1bad701 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -120,6 +120,9 @@
                    MK_PTR(MK_STRUCT(STRUCT_fiemap)))
 #endif
 
+     IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_INT))
+     IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_INT))
+
   IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
   IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
   IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index c0c9b58..c0e5cb0 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -998,6 +998,12 @@ struct target_pollfd {
 
 #define TARGET_FIBMAP     TARGET_IO(0x00,1)  /* bmap access */
 #define TARGET_FIGETBSZ   TARGET_IO(0x00,2)  /* get the block size used for bmap */
+/* Note that the ioctl numbers claim type "long" but the actual type
+ * used by the kernel is "int".
+ */
+#define TARGET_FS_IOC_GETFLAGS TARGET_IOR('f', 1, long)
+#define TARGET_FS_IOC_SETFLAGS TARGET_IOW('f', 2, long)
+
 #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
 
 /* cdrom commands */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 05/26] linux-user: Use direct syscall for utimensat
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (3 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 04/26] linux-user: Implement FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 06/26] linux-user: Check for bad event numbers in epoll_wait riku.voipio
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

The linux utimensat syscall differs in semantics from the
libc function because the syscall combines the features
of utimensat() and futimens(). Rather than trying to
split these apart in order to call the two libc functions
which then call the same underlying syscall, just always
directly make the host syscall. This fixes bugs in some
of the corner cases which should return errors from the
syscall but which we were incorrectly directing to futimens().

This doesn't reduce the set of hosts that our syscall
implementation will work on, because if the direct syscall
fails ENOSYS then the libc functions would also fail ENOSYS.
(The system call has been in the kernel since 2.6.22 anyway.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 51f558d..21ae996 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -520,16 +520,7 @@ static int sys_getcwd1(char *buf, size_t size)
 }
 
 #ifdef TARGET_NR_utimensat
-#ifdef CONFIG_UTIMENSAT
-static int sys_utimensat(int dirfd, const char *pathname,
-    const struct timespec times[2], int flags)
-{
-    if (pathname == NULL)
-        return futimens(dirfd, times);
-    else
-        return utimensat(dirfd, pathname, times, flags);
-}
-#elif defined(__NR_utimensat)
+#if defined(__NR_utimensat)
 #define __NR_sys_utimensat __NR_utimensat
 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
           const struct timespec *,tsp,int,flags)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 06/26] linux-user: Check for bad event numbers in epoll_wait
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (4 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 05/26] linux-user: Use direct syscall for utimensat riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 07/26] linux-user: Range check the nfds argument to ppoll syscall riku.voipio
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

The kernel checks that the maxevents parameter to epoll_wait
is non-negative and not larger than EP_MAX_EVENTS. Add this
check to our implementation, so that:
 * we fail these cases EINVAL rather than EFAULT
 * we don't pass negative or overflowing values to the
   lock_user() size calculation

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c      | 5 +++++
 linux-user/syscall_defs.h | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 21ae996..eecccbb 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11501,6 +11501,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         int maxevents = arg3;
         int timeout = arg4;
 
+        if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
+            ret = -TARGET_EINVAL;
+            break;
+        }
+
         target_ep = lock_user(VERIFY_WRITE, arg2,
                               maxevents * sizeof(struct target_epoll_event), 1);
         if (!target_ep) {
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index c0e5cb0..5c19c5c 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2585,6 +2585,9 @@ struct target_epoll_event {
     abi_uint events;
     target_epoll_data_t data;
 } TARGET_EPOLL_PACKED;
+
+#define TARGET_EP_MAX_EVENTS (INT_MAX / sizeof(struct target_epoll_event))
+
 #endif
 struct target_rlimit64 {
     uint64_t rlim_cur;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 07/26] linux-user: Range check the nfds argument to ppoll syscall
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (5 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 06/26] linux-user: Check for bad event numbers in epoll_wait riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 08/26] linux-user: report signals being taken in strace output riku.voipio
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

Do an initial range check on the ppoll syscall's nfds argument,
to avoid possible overflow in the calculation of the lock_user()
size argument. The host kernel will later apply the rather lower
limit based on RLIMIT_NOFILE as appropriate.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index eecccbb..7a50a57 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9661,6 +9661,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             pfd = NULL;
             target_pfd = NULL;
             if (nfds) {
+                if (nfds > (INT_MAX / sizeof(struct target_pollfd))) {
+                    ret = -TARGET_EINVAL;
+                    break;
+                }
+
                 target_pfd = lock_user(VERIFY_WRITE, arg1,
                                        sizeof(struct target_pollfd) * nfds, 1);
                 if (!target_pfd) {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 08/26] linux-user: report signals being taken in strace output
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (6 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 07/26] linux-user: Range check the nfds argument to ppoll syscall riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 09/26] linux-user: Pass missing MAP_ANONYMOUS to target_mmap() call riku.voipio
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

Native strace reports when the process being traced takes a signal:
   --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---

Report something similar when QEMU is doing its internal strace of
the guest process and is about to deliver it a signal.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/qemu.h   |  10 +++++
 linux-user/signal.c |   4 ++
 linux-user/strace.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 120 insertions(+)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 815447f..61808f6 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -362,6 +362,16 @@ void print_syscall(int num,
                    abi_long arg1, abi_long arg2, abi_long arg3,
                    abi_long arg4, abi_long arg5, abi_long arg6);
 void print_syscall_ret(int num, abi_long arg1);
+/**
+ * print_taken_signal:
+ * @target_signum: target signal being taken
+ * @tinfo: target_siginfo_t which will be passed to the guest for the signal
+ *
+ * Print strace output indicating that this signal is being taken by the guest,
+ * in a format similar to:
+ * --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
+ */
+void print_taken_signal(int target_signum, const target_siginfo_t *tinfo);
 extern int do_strace;
 
 /* signal.c */
diff --git a/linux-user/signal.c b/linux-user/signal.c
index d3ac0e2..3337f1e 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -5849,6 +5849,10 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
         handler = sa->_sa_handler;
     }
 
+    if (do_strace) {
+        print_taken_signal(sig, &k->info);
+    }
+
     if (handler == TARGET_SIG_DFL) {
         /* default handler : ignore some signal. The other are job control or fatal */
         if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {
diff --git a/linux-user/strace.c b/linux-user/strace.c
index cc10dc4..1e51360 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -154,6 +154,100 @@ print_signal(abi_ulong arg, int last)
     gemu_log("%s%s", signal_name, get_comma(last));
 }
 
+static void print_si_code(int arg)
+{
+    const char *codename = NULL;
+
+    switch (arg) {
+    case SI_USER:
+        codename = "SI_USER";
+        break;
+    case SI_KERNEL:
+        codename = "SI_KERNEL";
+        break;
+    case SI_QUEUE:
+        codename = "SI_QUEUE";
+        break;
+    case SI_TIMER:
+        codename = "SI_TIMER";
+        break;
+    case SI_MESGQ:
+        codename = "SI_MESGQ";
+        break;
+    case SI_ASYNCIO:
+        codename = "SI_ASYNCIO";
+        break;
+    case SI_SIGIO:
+        codename = "SI_SIGIO";
+        break;
+    case SI_TKILL:
+        codename = "SI_TKILL";
+        break;
+    default:
+        gemu_log("%d", arg);
+        return;
+    }
+    gemu_log("%s", codename);
+}
+
+static void print_siginfo(const target_siginfo_t *tinfo)
+{
+    /* Print a target_siginfo_t in the format desired for printing
+     * signals being taken. We assume the target_siginfo_t is in the
+     * internal form where the top 16 bits of si_code indicate which
+     * part of the union is valid, rather than in the guest-visible
+     * form where the bottom 16 bits are sign-extended into the top 16.
+     */
+    int si_type = extract32(tinfo->si_code, 16, 16);
+    int si_code = sextract32(tinfo->si_code, 0, 16);
+
+    gemu_log("{si_signo=");
+    print_signal(tinfo->si_signo, 1);
+    gemu_log(", si_code=");
+    print_si_code(si_code);
+
+    switch (si_type) {
+    case QEMU_SI_KILL:
+        gemu_log(", si_pid = %u, si_uid = %u",
+                 (unsigned int)tinfo->_sifields._kill._pid,
+                 (unsigned int)tinfo->_sifields._kill._uid);
+        break;
+    case QEMU_SI_TIMER:
+        gemu_log(", si_timer1 = %u, si_timer2 = %u",
+                 tinfo->_sifields._timer._timer1,
+                 tinfo->_sifields._timer._timer2);
+        break;
+    case QEMU_SI_POLL:
+        gemu_log(", si_band = %d, si_fd = %d",
+                 tinfo->_sifields._sigpoll._band,
+                 tinfo->_sifields._sigpoll._fd);
+        break;
+    case QEMU_SI_FAULT:
+        gemu_log(", si_addr = ");
+        print_pointer(tinfo->_sifields._sigfault._addr, 1);
+        break;
+    case QEMU_SI_CHLD:
+        gemu_log(", si_pid = %u, si_uid = %u, si_status = %d"
+                 ", si_utime=" TARGET_ABI_FMT_ld
+                 ", si_stime=" TARGET_ABI_FMT_ld,
+                 (unsigned int)(tinfo->_sifields._sigchld._pid),
+                 (unsigned int)(tinfo->_sifields._sigchld._uid),
+                 tinfo->_sifields._sigchld._status,
+                 tinfo->_sifields._sigchld._utime,
+                 tinfo->_sifields._sigchld._stime);
+        break;
+    case QEMU_SI_RT:
+        gemu_log(", si_pid = %u, si_uid = %u, si_sigval = " TARGET_ABI_FMT_ld,
+                 (unsigned int)tinfo->_sifields._rt._pid,
+                 (unsigned int)tinfo->_sifields._rt._uid,
+                 tinfo->_sifields._rt._sigval.sival_ptr);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    gemu_log("}");
+}
+
 static void
 print_sockaddr(abi_ulong addr, abi_long addrlen)
 {
@@ -2190,3 +2284,15 @@ print_syscall_ret(int num, abi_long ret)
             break;
         }
 }
+
+void print_taken_signal(int target_signum, const target_siginfo_t *tinfo)
+{
+    /* Print the strace output for a signal being taken:
+     * --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
+     */
+    gemu_log("--- ");
+    print_signal(target_signum, 1);
+    gemu_log(" ");
+    print_siginfo(tinfo);
+    gemu_log(" ---\n");
+}
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 09/26] linux-user: Pass missing MAP_ANONYMOUS to target_mmap() call
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (7 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 08/26] linux-user: report signals being taken in strace output riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 10/26] linux-user: Check lock_user() return value for NULL riku.voipio
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

A target_mmap() call in load_elf_binary() was missing the MAP_ANONYMOUS
flag. (Spotted by Coverity, because target_mmap() will try to use
-1 as the filedescriptor in this case.)

This has never been noticed because the code in question is for
handling ancient SVr4 iBCS2 binaries.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/elfload.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 29455e4..e9a3882 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2233,7 +2233,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
                we do not have the power to recompile these, we emulate
                the SVr4 behavior.  Sigh.  */
             target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC,
-                        MAP_FIXED | MAP_PRIVATE, -1, 0);
+                        MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
         }
     }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 10/26] linux-user: Check lock_user() return value for NULL
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (8 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 09/26] linux-user: Pass missing MAP_ANONYMOUS to target_mmap() call riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 11/26] linux-user: Fix incorrect use of host errno in do_ioctl_dm() riku.voipio
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

lock_user() can return NULL, which typically means the syscall
should fail with EFAULT. Add checks in various places where
Coverity spotted that we were missing them.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7a50a57..efcc17a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5008,6 +5008,11 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
     host_data = (char*)host_dm + host_dm->data_start;
 
     argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
+    if (!argptr) {
+        ret = -TARGET_EFAULT;
+        goto out;
+    }
+
     switch (ie->host_cmd) {
     case DM_REMOVE_ALL:
     case DM_LIST_DEVICES:
@@ -11271,6 +11276,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 
     case TARGET_NR_mq_unlink:
         p = lock_user_string(arg1 - 1);
+        if (!p) {
+            ret = -TARGET_EFAULT;
+            break;
+        }
         ret = get_errno(mq_unlink(p));
         unlock_user (p, arg1, 0);
         break;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 11/26] linux-user: Fix incorrect use of host errno in do_ioctl_dm()
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (9 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 10/26] linux-user: Check lock_user() return value for NULL riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 12/26] linux-user: Fix error handling in flatload.c target_pread() riku.voipio
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

do_ioctl_dm() should return target errno values, not host ones;
correct an accidental use of a host errno in an error path.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index efcc17a..e286907 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5001,7 +5001,7 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
 
     guest_data = arg + host_dm->data_start;
     if ((guest_data - arg) < 0) {
-        ret = -EINVAL;
+        ret = -TARGET_EINVAL;
         goto out;
     }
     guest_data_size = host_dm->data_size - host_dm->data_start;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 12/26] linux-user: Fix error handling in flatload.c target_pread()
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (10 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 11/26] linux-user: Fix incorrect use of host errno in do_ioctl_dm() riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 13/26] linux-user: Check dump_write() return in elf_core_dump() riku.voipio
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

The flatload.c target_pread() function is supposed to return
0 on success or negative host errnos; however it wasn't
checking lock_user() for failure or returning the errno from
the pread() call. Fix these problems (the first of which is
noted by Coverity).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/flatload.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index 42d1079..a35a560 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -95,7 +95,13 @@ static int target_pread(int fd, abi_ulong ptr, abi_ulong len,
     int ret;
 
     buf = lock_user(VERIFY_WRITE, ptr, len, 0);
+    if (!buf) {
+        return -EFAULT;
+    }
     ret = pread(fd, buf, len, offset);
+    if (ret < 0) {
+        ret = -errno;
+    }
     unlock_user(buf, ptr, len);
     return ret;
 }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 13/26] linux-user: Check dump_write() return in elf_core_dump()
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (11 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 12/26] linux-user: Fix error handling in flatload.c target_pread() riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 14/26] linux-user: Use glib malloc functions in load_symbols() riku.voipio
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

One of the calls to dump_write() in elf_core_dump() was missing
a check for failure (spotted by Coverity). Add the check to
bring it into line with the other calls from this function.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/elfload.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e9a3882..0d07b85 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -3050,7 +3050,9 @@ static int elf_core_dump(int signr, const CPUArchState *env)
         phdr.p_align = ELF_EXEC_PAGESIZE;
 
         bswap_phdr(&phdr, 1);
-        dump_write(fd, &phdr, sizeof (phdr));
+        if (dump_write(fd, &phdr, sizeof(phdr)) != 0) {
+            goto out;
+        }
     }
 
     /*
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 14/26] linux-user: Use glib malloc functions in load_symbols()
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (12 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 13/26] linux-user: Check dump_write() return in elf_core_dump() riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 15/26] linux-user: Use correct target SHMLBA in shmat() riku.voipio
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

Switch to using the glib malloc functions in load_symbols();
this deals with a Coverity complaint about possible
integer overflow calculating the allocation size with
'nsyms * sizeof(*syms)'.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/elfload.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0d07b85..3d751f8 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2111,19 +2111,19 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
 
  found:
     /* Now know where the strtab and symtab are.  Snarf them.  */
-    s = malloc(sizeof(*s));
+    s = g_try_new(struct syminfo, 1);
     if (!s) {
         goto give_up;
     }
 
     i = shdr[str_idx].sh_size;
-    s->disas_strtab = strings = malloc(i);
+    s->disas_strtab = strings = g_try_malloc(i);
     if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) {
         goto give_up;
     }
 
     i = shdr[sym_idx].sh_size;
-    syms = malloc(i);
+    syms = g_try_malloc(i);
     if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) {
         goto give_up;
     }
@@ -2157,7 +2157,7 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
        that we threw away.  Whether or not this has any effect on the
        memory allocation depends on the malloc implementation and how
        many symbols we managed to discard.  */
-    new_syms = realloc(syms, nsyms * sizeof(*syms));
+    new_syms = g_try_renew(struct elf_sym, syms, nsyms);
     if (new_syms == NULL) {
         goto give_up;
     }
@@ -2178,9 +2178,9 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
     return;
 
 give_up:
-    free(s);
-    free(strings);
-    free(syms);
+    g_free(s);
+    g_free(strings);
+    g_free(syms);
 }
 
 int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 15/26] linux-user: Use correct target SHMLBA in shmat()
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (13 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 14/26] linux-user: Use glib malloc functions in load_symbols() riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 16/26] linux-user: ppc64: set MSR_CM bit for BookE 2.06 MMU riku.voipio
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

The shmat() handling needs to do target-specific handling
of the attach address for shmat():
 * if the SHM_RND flag is passed, the address is rounded
   down to a SHMLBA boundary
 * if SHM_RND is not passed, then the call is failed EINVAL
   if the address is not a multiple of SHMLBA

Since SHMLBA is target-specific, we need to do this
checking and rounding in QEMU and can't leave it up to the
host syscall.

Allow targets to define TARGET_FORCE_SHMLBA and provide
a target_shmlba() function if appropriate, and update
do_shmat() to honour them.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/arm/target_syscall.h    |  7 ++++++
 linux-user/mips/target_syscall.h   |  7 ++++++
 linux-user/mips64/target_syscall.h |  7 ++++++
 linux-user/sh4/target_syscall.h    |  7 ++++++
 linux-user/sparc/target_syscall.h  | 16 ++++++++++++++
 linux-user/syscall.c               | 45 +++++++++++++++++++++++++++++++++-----
 6 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/linux-user/arm/target_syscall.h b/linux-user/arm/target_syscall.h
index cd021ff..0879b4d 100644
--- a/linux-user/arm/target_syscall.h
+++ b/linux-user/arm/target_syscall.h
@@ -33,4 +33,11 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
+#define TARGET_FORCE_SHMLBA
+
+static inline abi_ulong target_shmlba(CPUARMState *env)
+{
+    return 4 * 4096;
+}
+
 #endif /* ARM_TARGET_SYSCALL_H */
diff --git a/linux-user/mips/target_syscall.h b/linux-user/mips/target_syscall.h
index 2b4f390..6c666dc 100644
--- a/linux-user/mips/target_syscall.h
+++ b/linux-user/mips/target_syscall.h
@@ -230,4 +230,11 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
+#define TARGET_FORCE_SHMLBA
+
+static inline abi_ulong target_shmlba(CPUMIPSState *env)
+{
+    return 0x40000;
+}
+
 #endif /* MIPS_TARGET_SYSCALL_H */
diff --git a/linux-user/mips64/target_syscall.h b/linux-user/mips64/target_syscall.h
index 8da9c1f..a9c17f7 100644
--- a/linux-user/mips64/target_syscall.h
+++ b/linux-user/mips64/target_syscall.h
@@ -227,4 +227,11 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
+#define TARGET_FORCE_SHMLBA
+
+static inline abi_ulong target_shmlba(CPUMIPSState *env)
+{
+    return 0x40000;
+}
+
 #endif /* MIPS64_TARGET_SYSCALL_H */
diff --git a/linux-user/sh4/target_syscall.h b/linux-user/sh4/target_syscall.h
index 78d5557..2b5f75b 100644
--- a/linux-user/sh4/target_syscall.h
+++ b/linux-user/sh4/target_syscall.h
@@ -19,4 +19,11 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
+#define TARGET_FORCE_SHMLBA
+
+static inline abi_ulong target_shmlba(CPUSH4State *env)
+{
+    return 0x4000;
+}
+
 #endif /* SH4_TARGET_SYSCALL_H */
diff --git a/linux-user/sparc/target_syscall.h b/linux-user/sparc/target_syscall.h
index 326f674..f97aa6b 100644
--- a/linux-user/sparc/target_syscall.h
+++ b/linux-user/sparc/target_syscall.h
@@ -22,4 +22,20 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 0x2000
 #define TARGET_MLOCKALL_MCL_FUTURE  0x4000
 
+/* For SPARC SHMLBA is determined at runtime in the kernel, and
+ * libc has to runtime-detect it using the hwcaps (see glibc
+ * sysdeps/unix/sysv/linux/sparc/getshmlba; we follow the same
+ * logic here, though we know we're not the sparc v9 64-bit case).
+ */
+#define TARGET_FORCE_SHMLBA
+
+static inline abi_ulong target_shmlba(CPUSPARCState *env)
+{
+    if (!(env->def->features & CPU_FEATURE_FLUSH)) {
+        return 64 * 1024;
+    } else {
+        return 256 * 1024;
+    }
+}
+
 #endif /* SPARC_TARGET_SYSCALL_H */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e286907..85699f9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4575,12 +4575,34 @@ static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
     return ret;
 }
 
-static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
+#ifndef TARGET_FORCE_SHMLBA
+/* For most architectures, SHMLBA is the same as the page size;
+ * some architectures have larger values, in which case they should
+ * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
+ * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
+ * and defining its own value for SHMLBA.
+ *
+ * The kernel also permits SHMLBA to be set by the architecture to a
+ * value larger than the page size without setting __ARCH_FORCE_SHMLBA;
+ * this means that addresses are rounded to the large size if
+ * SHM_RND is set but addresses not aligned to that size are not rejected
+ * as long as they are at least page-aligned. Since the only architecture
+ * which uses this is ia64 this code doesn't provide for that oddity.
+ */
+static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
+{
+    return TARGET_PAGE_SIZE;
+}
+#endif
+
+static inline abi_ulong do_shmat(CPUArchState *cpu_env,
+                                 int shmid, abi_ulong shmaddr, int shmflg)
 {
     abi_long raddr;
     void *host_raddr;
     struct shmid_ds shm_info;
     int i,ret;
+    abi_ulong shmlba;
 
     /* find out the length of the shared memory segment */
     ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
@@ -4589,6 +4611,16 @@ static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
         return ret;
     }
 
+    shmlba = target_shmlba(cpu_env);
+
+    if (shmaddr & (shmlba - 1)) {
+        if (shmflg & SHM_RND) {
+            shmaddr &= ~(shmlba - 1);
+        } else {
+            return -TARGET_EINVAL;
+        }
+    }
+
     mmap_lock();
 
     if (shmaddr)
@@ -4647,7 +4679,8 @@ static inline abi_long do_shmdt(abi_ulong shmaddr)
 #ifdef TARGET_NR_ipc
 /* ??? This only works with linear mappings.  */
 /* do_ipc() must return target values and target errnos. */
-static abi_long do_ipc(unsigned int call, abi_long first,
+static abi_long do_ipc(CPUArchState *cpu_env,
+                       unsigned int call, abi_long first,
                        abi_long second, abi_long third,
                        abi_long ptr, abi_long fifth)
 {
@@ -4716,7 +4749,7 @@ static abi_long do_ipc(unsigned int call, abi_long first,
         default:
         {
             abi_ulong raddr;
-            raddr = do_shmat(first, ptr, second);
+            raddr = do_shmat(cpu_env, first, ptr, second);
             if (is_error(raddr))
                 return get_errno(raddr);
             if (put_user_ual(raddr, third))
@@ -9304,8 +9337,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #ifdef TARGET_NR_ipc
     case TARGET_NR_ipc:
-	ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
-	break;
+        ret = do_ipc(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
+        break;
 #endif
 #ifdef TARGET_NR_semget
     case TARGET_NR_semget:
@@ -9354,7 +9387,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_shmat
     case TARGET_NR_shmat:
-        ret = do_shmat(arg1, arg2, arg3);
+        ret = do_shmat(cpu_env, arg1, arg2, arg3);
         break;
 #endif
 #ifdef TARGET_NR_shmdt
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 16/26] linux-user: ppc64: set MSR_CM bit for BookE 2.06 MMU
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (14 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 15/26] linux-user: Use correct target SHMLBA in shmat() riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 17/26] linux-user: Recheck for pending synchronous signals too riku.voipio
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Michael Walle

From: Michael Walle <michael@walle.cc>

64 bit user mode doesn't work for the e5500 core because the MSR_CM bit is
not set which enables the 64 bit mode for this MMU model. Memory addresses
are truncated to 32 bit, which results in "Invalid data memory access"
error messages. Fix it by setting the MSR_CM bit for this MMU model.

Signed-off-by: Michael Walle <michael@walle.cc>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 3ad70f8..2aeda8a 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -4615,10 +4615,11 @@ int main(int argc, char **argv, char **envp)
         int i;
 
 #if defined(TARGET_PPC64)
+        int flag = (env->insns_flags2 & PPC2_BOOKE206) ? MSR_CM : MSR_SF;
 #if defined(TARGET_ABI32)
-        env->msr &= ~((target_ulong)1 << MSR_SF);
+        env->msr &= ~((target_ulong)1 << flag);
 #else
-        env->msr |= (target_ulong)1 << MSR_SF;
+        env->msr |= (target_ulong)1 << flag;
 #endif
 #endif
         env->nip = regs->nip;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 17/26] linux-user: Recheck for pending synchronous signals too
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (15 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 16/26] linux-user: ppc64: set MSR_CM bit for BookE 2.06 MMU riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 18/26] linux-user: Pass si_type information to queue_signal() explicitly riku.voipio
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

In process_pending_signals() we restart the scan of possible
pending signals after calling handle_pending_signal() in
case some other signal has been generated. This rescan
should also include a check for a new synchronous signal
since those are in fact the only kind of new signal that
the signal frame setup process might produce.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/signal.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 3337f1e..f2c9f8e 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -5925,6 +5925,7 @@ void process_pending_signals(CPUArchState *cpu_env)
         sigfillset(&set);
         sigprocmask(SIG_SETMASK, &set, 0);
 
+    restart_scan:
         sig = ts->sync_signal.pending;
         if (sig) {
             /* Synchronous signals are forced,
@@ -5952,8 +5953,10 @@ void process_pending_signals(CPUArchState *cpu_env)
                 (!sigismember(blocked_set,
                               target_to_host_signal_table[sig]))) {
                 handle_pending_signal(cpu_env, sig, &ts->sigtab[sig - 1]);
-                /* Restart scan from the beginning */
-                sig = 1;
+                /* Restart scan from the beginning, as handle_pending_signal
+                 * might have resulted in a new synchronous signal (eg SIGSEGV).
+                 */
+                goto restart_scan;
             }
         }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 18/26] linux-user: Pass si_type information to queue_signal() explicitly
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (16 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 17/26] linux-user: Recheck for pending synchronous signals too riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 19/26] linux-user: SIGSEGV on signal entry need not be fatal riku.voipio
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

Instead of assuming in queue_signal() that all callers are passing
a siginfo structure which uses the _sifields._sigfault part of the
union (and thus a si_type of QEMU_SI_FAULT), make callers pass
the si_type they require in as an argument.

[RV adjusted to apply]
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/main.c    | 124 +++++++++++++++++++++++++--------------------------
 linux-user/qemu.h    |   3 +-
 linux-user/signal.c  |  10 ++---
 linux-user/syscall.c |   6 ++-
 4 files changed, 71 insertions(+), 72 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 2aeda8a..aba58c7 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -339,7 +339,7 @@ void cpu_loop(CPUX86State *env)
             info.si_errno = 0;
             info.si_code = TARGET_SI_KERNEL;
             info._sifields._sigfault._addr = 0;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP0D_GPF:
             /* XXX: potential problem if ABI32 */
@@ -353,7 +353,7 @@ void cpu_loop(CPUX86State *env)
                 info.si_errno = 0;
                 info.si_code = TARGET_SI_KERNEL;
                 info._sifields._sigfault._addr = 0;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP0E_PAGE:
@@ -364,7 +364,7 @@ void cpu_loop(CPUX86State *env)
             else
                 info.si_code = TARGET_SEGV_ACCERR;
             info._sifields._sigfault._addr = env->cr[2];
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP00_DIVZ:
 #ifndef TARGET_X86_64
@@ -378,7 +378,7 @@ void cpu_loop(CPUX86State *env)
                 info.si_errno = 0;
                 info.si_code = TARGET_FPE_INTDIV;
                 info._sifields._sigfault._addr = env->eip;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP01_DB:
@@ -398,7 +398,7 @@ void cpu_loop(CPUX86State *env)
                     info.si_code = TARGET_SI_KERNEL;
                     info._sifields._sigfault._addr = 0;
                 }
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP04_INTO:
@@ -413,7 +413,7 @@ void cpu_loop(CPUX86State *env)
                 info.si_errno = 0;
                 info.si_code = TARGET_SI_KERNEL;
                 info._sifields._sigfault._addr = 0;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP06_ILLOP:
@@ -421,7 +421,7 @@ void cpu_loop(CPUX86State *env)
             info.si_errno = 0;
             info.si_code = TARGET_ILL_ILLOPN;
             info._sifields._sigfault._addr = env->eip;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
@@ -436,7 +436,7 @@ void cpu_loop(CPUX86State *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -576,7 +576,7 @@ segv:
     /* XXX: check env->error_code */
     info.si_code = TARGET_SEGV_MAPERR;
     info._sifields._sigfault._addr = env->exception.vaddress;
-    queue_signal(env, info.si_signo, &info);
+    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 }
 
 /* Handle a jump to the kernel code page.  */
@@ -755,7 +755,7 @@ void cpu_loop(CPUARMState *env)
                     info.si_errno = 0;
                     info.si_code = TARGET_ILL_ILLOPN;
                     info._sifields._sigfault._addr = env->regs[15];
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                 } else if (rc < 0) { /* FP exception */
                     int arm_fpe=0;
 
@@ -786,7 +786,7 @@ void cpu_loop(CPUARMState *env)
                       if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
 
                       info._sifields._sigfault._addr = env->regs[15];
-                      queue_signal(env, info.si_signo, &info);
+                      queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                     } else {
                       env->regs[15] += 4;
                     }
@@ -907,7 +907,7 @@ void cpu_loop(CPUARMState *env)
                 /* XXX: check env->error_code */
                 info.si_code = TARGET_SEGV_MAPERR;
                 info._sifields._sigfault._addr = addr;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP_DEBUG:
@@ -921,7 +921,7 @@ void cpu_loop(CPUARMState *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -1099,7 +1099,7 @@ void cpu_loop(CPUARMState *env)
             info.si_errno = 0;
             info.si_code = TARGET_ILL_ILLOPN;
             info._sifields._sigfault._addr = env->pc;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_STREX:
             if (!do_strex_a64(env)) {
@@ -1113,7 +1113,7 @@ void cpu_loop(CPUARMState *env)
             /* XXX: check env->error_code */
             info.si_code = TARGET_SEGV_MAPERR;
             info._sifields._sigfault._addr = env->exception.vaddress;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_DEBUG:
         case EXCP_BKPT:
@@ -1122,7 +1122,7 @@ void cpu_loop(CPUARMState *env)
                 info.si_signo = sig;
                 info.si_errno = 0;
                 info.si_code = TARGET_TRAP_BRKPT;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP_SEMIHOST:
@@ -1202,7 +1202,7 @@ void cpu_loop(CPUUniCore32State *env)
             /* XXX: check env->error_code */
             info.si_code = TARGET_SEGV_MAPERR;
             info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
@@ -1216,7 +1216,7 @@ void cpu_loop(CPUUniCore32State *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                 }
             }
             break;
@@ -1431,7 +1431,7 @@ void cpu_loop (CPUSPARCState *env)
                 /* XXX: check env->error_code */
                 info.si_code = TARGET_SEGV_MAPERR;
                 info._sifields._sigfault._addr = env->mmuregs[4];
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
 #else
@@ -1452,7 +1452,7 @@ void cpu_loop (CPUSPARCState *env)
                     info._sifields._sigfault._addr = env->dmmuregs[4];
                 else
                     info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
 #ifndef TARGET_ABI32
@@ -1475,7 +1475,7 @@ void cpu_loop (CPUSPARCState *env)
                 info.si_errno = 0;
                 info.si_code = TARGET_ILL_ILLOPC;
                 info._sifields._sigfault._addr = env->pc;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP_DEBUG:
@@ -1488,7 +1488,7 @@ void cpu_loop (CPUSPARCState *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -1679,7 +1679,7 @@ void cpu_loop(CPUPPCState *env)
                 break;
             }
             info._sifields._sigfault._addr = env->nip;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_ISI:      /* Instruction storage exception         */
             /* XXX: check this */
@@ -1705,7 +1705,7 @@ void cpu_loop(CPUPPCState *env)
                 break;
             }
             info._sifields._sigfault._addr = env->nip - 4;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_EXTERNAL: /* External input                        */
             cpu_abort(cs, "External interrupt while in user mode. "
@@ -1717,7 +1717,7 @@ void cpu_loop(CPUPPCState *env)
             info.si_errno = 0;
             info.si_code = TARGET_BUS_ADRALN;
             info._sifields._sigfault._addr = env->nip;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
         case POWERPC_EXCP_HV_EMU:   /* HV emulation                          */
@@ -1808,14 +1808,14 @@ void cpu_loop(CPUPPCState *env)
                 break;
             }
             info._sifields._sigfault._addr = env->nip;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_FPU:      /* Floating-point unavailable exception  */
             info.si_signo = TARGET_SIGILL;
             info.si_errno = 0;
             info.si_code = TARGET_ILL_COPROC;
             info._sifields._sigfault._addr = env->nip;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
             cpu_abort(cs, "Syscall exception while in user mode. "
@@ -1826,7 +1826,7 @@ void cpu_loop(CPUPPCState *env)
             info.si_errno = 0;
             info.si_code = TARGET_ILL_COPROC;
             info._sifields._sigfault._addr = env->nip;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_DECR:     /* Decrementer exception                 */
             cpu_abort(cs, "Decrementer interrupt while in user mode. "
@@ -1853,7 +1853,7 @@ void cpu_loop(CPUPPCState *env)
             info.si_errno = 0;
             info.si_code = TARGET_ILL_COPROC;
             info._sifields._sigfault._addr = env->nip;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_EFPDI:    /* Embedded floating-point data IRQ      */
             cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
@@ -1916,7 +1916,7 @@ void cpu_loop(CPUPPCState *env)
             info.si_errno = 0;
             info.si_code = TARGET_ILL_COPROC;
             info._sifields._sigfault._addr = env->nip;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_PIT:      /* Programmable interval timer IRQ       */
             cpu_abort(cs, "Programmable interval timer interrupt "
@@ -2010,7 +2010,7 @@ void cpu_loop(CPUPPCState *env)
                 info.si_errno = 0;
                 info.si_code = TARGET_SEGV_MAPERR;
                 info._sifields._sigfault._addr = env->nip;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP_DEBUG:
@@ -2022,7 +2022,7 @@ void cpu_loop(CPUPPCState *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -2456,13 +2456,13 @@ static int do_break(CPUMIPSState *env, target_siginfo_t *info,
         info->si_signo = TARGET_SIGFPE;
         info->si_errno = 0;
         info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
-        queue_signal(env, info->si_signo, &*info);
+        queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
         ret = 0;
         break;
     default:
         info->si_signo = TARGET_SIGTRAP;
         info->si_errno = 0;
-        queue_signal(env, info->si_signo, &*info);
+        queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
         ret = 0;
         break;
     }
@@ -2560,14 +2560,14 @@ done_syscall:
             /* XXX: check env->error_code */
             info.si_code = TARGET_SEGV_MAPERR;
             info._sifields._sigfault._addr = env->CP0_BadVAddr;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_CpU:
         case EXCP_RI:
             info.si_signo = TARGET_SIGILL;
             info.si_errno = 0;
             info.si_code = 0;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
@@ -2582,7 +2582,7 @@ done_syscall:
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -2592,14 +2592,14 @@ done_syscall:
                 info.si_errno = 0;
                 info.si_code = TARGET_SEGV_MAPERR;
                 info._sifields._sigfault._addr = env->active_tc.PC;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP_DSPDIS:
             info.si_signo = TARGET_SIGILL;
             info.si_errno = 0;
             info.si_code = TARGET_ILL_ILLOPC;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         /* The code below was inspired by the MIPS Linux kernel trap
          * handling code in arch/mips/kernel/traps.c.
@@ -2850,7 +2850,7 @@ void cpu_loop(CPUSH4State *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -2860,7 +2860,7 @@ void cpu_loop(CPUSH4State *env)
             info.si_errno = 0;
             info.si_code = TARGET_SEGV_MAPERR;
             info._sifields._sigfault._addr = env->tea;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 	    break;
 
         default:
@@ -2892,7 +2892,7 @@ void cpu_loop(CPUCRISState *env)
                 /* XXX: check env->error_code */
                 info.si_code = TARGET_SEGV_MAPERR;
                 info._sifields._sigfault._addr = env->pregs[PR_EDA];
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
 	case EXCP_INTERRUPT:
@@ -2924,7 +2924,7 @@ void cpu_loop(CPUCRISState *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -2957,7 +2957,7 @@ void cpu_loop(CPUMBState *env)
                 /* XXX: check env->error_code */
                 info.si_code = TARGET_SEGV_MAPERR;
                 info._sifields._sigfault._addr = 0;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
 	case EXCP_INTERRUPT:
@@ -3006,7 +3006,7 @@ void cpu_loop(CPUMBState *env)
                     info.si_errno = 0;
                     info.si_code = TARGET_FPE_FLTDIV;
                     info._sifields._sigfault._addr = 0;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                     break;
                 case ESR_EC_FPU:
                     info.si_signo = TARGET_SIGFPE;
@@ -3018,7 +3018,7 @@ void cpu_loop(CPUMBState *env)
                         info.si_code = TARGET_FPE_FLTDIV;
                     }
                     info._sifields._sigfault._addr = 0;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                     break;
                 default:
                     printf ("Unhandled hw-exception: 0x%x\n",
@@ -3038,7 +3038,7 @@ void cpu_loop(CPUMBState *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -3092,7 +3092,7 @@ void cpu_loop(CPUM68KState *env)
             info.si_errno = 0;
             info.si_code = TARGET_ILL_ILLOPN;
             info._sifields._sigfault._addr = env->pc;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_TRAP0:
             {
@@ -3126,7 +3126,7 @@ void cpu_loop(CPUM68KState *env)
                 /* XXX: check env->error_code */
                 info.si_code = TARGET_SEGV_MAPERR;
                 info._sifields._sigfault._addr = env->mmu.ar;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP_DEBUG:
@@ -3139,7 +3139,7 @@ void cpu_loop(CPUM68KState *env)
                     info.si_signo = sig;
                     info.si_errno = 0;
                     info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
+                    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                   }
             }
             break;
@@ -3195,7 +3195,7 @@ static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
     info.si_errno = 0;
     info.si_code = TARGET_SEGV_MAPERR;
     info._sifields._sigfault._addr = addr;
-    queue_signal(env, TARGET_SIGSEGV, &info);
+    queue_signal(env, TARGET_SIGSEGV, QEMU_SI_FAULT, &info);
 }
 
 void cpu_loop(CPUAlphaState *env)
@@ -3237,7 +3237,7 @@ void cpu_loop(CPUAlphaState *env)
             info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
                             ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
             info._sifields._sigfault._addr = env->trap_arg0;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_UNALIGN:
             env->lock_addr = -1;
@@ -3245,7 +3245,7 @@ void cpu_loop(CPUAlphaState *env)
             info.si_errno = 0;
             info.si_code = TARGET_BUS_ADRALN;
             info._sifields._sigfault._addr = env->trap_arg0;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_OPCDEC:
         do_sigill:
@@ -3254,7 +3254,7 @@ void cpu_loop(CPUAlphaState *env)
             info.si_errno = 0;
             info.si_code = TARGET_ILL_ILLOPC;
             info._sifields._sigfault._addr = env->pc;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_ARITH:
             env->lock_addr = -1;
@@ -3262,7 +3262,7 @@ void cpu_loop(CPUAlphaState *env)
             info.si_errno = 0;
             info.si_code = TARGET_FPE_FLTINV;
             info._sifields._sigfault._addr = env->pc;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case EXCP_FEN:
             /* No-op.  Linux simply re-enables the FPU.  */
@@ -3276,7 +3276,7 @@ void cpu_loop(CPUAlphaState *env)
                 info.si_errno = 0;
                 info.si_code = TARGET_TRAP_BRKPT;
                 info._sifields._sigfault._addr = env->pc;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                 break;
             case 0x81:
                 /* BUGCHK */
@@ -3284,7 +3284,7 @@ void cpu_loop(CPUAlphaState *env)
                 info.si_errno = 0;
                 info.si_code = 0;
                 info._sifields._sigfault._addr = env->pc;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                 break;
             case 0x83:
                 /* CALLSYS */
@@ -3356,7 +3356,7 @@ void cpu_loop(CPUAlphaState *env)
                 }
                 info.si_errno = 0;
                 info._sifields._sigfault._addr = env->pc;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
                 break;
             default:
                 goto do_sigill;
@@ -3368,7 +3368,7 @@ void cpu_loop(CPUAlphaState *env)
                 env->lock_addr = -1;
                 info.si_errno = 0;
                 info.si_code = TARGET_TRAP_BRKPT;
-                queue_signal(env, info.si_signo, &info);
+                queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             }
             break;
         case EXCP_STL_C:
@@ -3502,7 +3502,7 @@ void cpu_loop(CPUS390XState *env)
             info.si_errno = 0;
             info.si_code = n;
             info._sifields._sigfault._addr = addr;
-            queue_signal(env, info.si_signo, &info);
+            queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
 
         default:
@@ -3526,7 +3526,7 @@ static void gen_sigill_reg(CPUTLGState *env)
     info.si_errno = 0;
     info.si_code = TARGET_ILL_PRVREG;
     info._sifields._sigfault._addr = env->pc;
-    queue_signal(env, info.si_signo, &info);
+    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 }
 
 static void do_signal(CPUTLGState *env, int signo, int sigcode)
@@ -3550,7 +3550,7 @@ static void do_signal(CPUTLGState *env, int signo, int sigcode)
     }
     info.si_code = sigcode;
 
-    queue_signal(env, info.si_signo, &info);
+    queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
 }
 
 static void gen_sigsegv_maperr(CPUTLGState *env, target_ulong addr)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 61808f6..da73a01 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -377,7 +377,8 @@ extern int do_strace;
 /* signal.c */
 void process_pending_signals(CPUArchState *cpu_env);
 void signal_init(void);
-int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info);
+int queue_signal(CPUArchState *env, int sig, int si_type,
+                 target_siginfo_t *info);
 void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
 void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
 int target_to_host_signal(int sig);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index f2c9f8e..93a9293 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -569,19 +569,15 @@ static void QEMU_NORETURN force_sig(int target_sig)
 
 /* queue a signal so that it will be send to the virtual CPU as soon
    as possible */
-int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
+int queue_signal(CPUArchState *env, int sig, int si_type,
+                 target_siginfo_t *info)
 {
     CPUState *cpu = ENV_GET_CPU(env);
     TaskState *ts = cpu->opaque;
 
     trace_user_queue_signal(env, sig);
 
-    /* Currently all callers define siginfo structures which
-     * use the _sifields._sigfault union member, so we can
-     * set the type here. If that changes we should push this
-     * out so the si_type is passed in by callers.
-     */
-    info->si_code = deposit32(info->si_code, 16, 16, QEMU_SI_FAULT);
+    info->si_code = deposit32(info->si_code, 16, 16, si_type);
 
     ts->sync_signal.info = *info;
     ts->sync_signal.pending = sig;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 85699f9..27ad6a2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10577,7 +10577,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     info.si_code = si_code;
                     info._sifields._sigfault._addr
                         = ((CPUArchState *)cpu_env)->pc;
-                    queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
+                    queue_signal((CPUArchState *)cpu_env, info.si_signo,
+                                 QEMU_SI_FAULT, &info);
                 }
             }
             break;
@@ -11665,7 +11666,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             info.si_errno = 0;
             info.si_code = TARGET_SEGV_MAPERR;
             info._sifields._sigfault._addr = arg6;
-            queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
+            queue_signal((CPUArchState *)cpu_env, info.si_signo,
+                         QEMU_SI_FAULT, &info);
             ret = 0xdeadbeef;
 
         }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 19/26] linux-user: SIGSEGV on signal entry need not be fatal
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (17 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 18/26] linux-user: Pass si_type information to queue_signal() explicitly riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 20/26] linux-user: ARM: Give SIGSEGV if signal frame setup fails riku.voipio
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

A failed write to memory trying to set up the signal frame
should trigger a SIGSEGV, but this need not be fatal: the
guest has a chance to catch it. Implement this via a force_sigsegv()
function with the same behaviour as the kernel function of that
name: make sure that we don't try to re-take a failed SIGSEGV,
and force a synchronous signal.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/signal.c | 87 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 49 insertions(+), 38 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 93a9293..892b527 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -512,6 +512,33 @@ void signal_init(void)
     }
 }
 
+#if !((defined(TARGET_ARM) && !defined(TARGET_AARCH64)) ||              \
+      defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
+
+/* Force a SIGSEGV if we couldn't write to memory trying to set
+ * up the signal frame. oldsig is the signal we were trying to handle
+ * at the point of failure.
+ */
+static void force_sigsegv(int oldsig)
+{
+    CPUState *cpu = thread_cpu;
+    CPUArchState *env = cpu->env_ptr;
+    target_siginfo_t info;
+
+    if (oldsig == SIGSEGV) {
+        /* Make sure we don't try to deliver the signal again; this will
+         * end up with handle_pending_signal() calling force_sig().
+         */
+        sigact_table[oldsig - 1]._sa_handler = TARGET_SIG_DFL;
+    }
+    info.si_signo = TARGET_SIGSEGV;
+    info.si_errno = 0;
+    info.si_code = TARGET_SI_KERNEL;
+    info._sifields._kill._pid = 0;
+    info._sifields._kill._uid = 0;
+    queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
+}
+#endif
 
 /* abort execution with signal */
 static void QEMU_NORETURN force_sig(int target_sig)
@@ -1011,10 +1038,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     return;
 
 give_sigsegv:
-    if (sig == TARGET_SIGSEGV) {
-        ka->_sa_handler = TARGET_SIG_DFL;
-    }
-    force_sig(TARGET_SIGSEGV /* , current */);
+    force_sigsegv(sig);
 }
 
 /* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
@@ -1084,10 +1108,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     return;
 
 give_sigsegv:
-    if (sig == TARGET_SIGSEGV) {
-        ka->_sa_handler = TARGET_SIG_DFL;
-    }
-    force_sig(TARGET_SIGSEGV /* , current */);
+    force_sigsegv(sig);
 }
 
 static int
@@ -1416,7 +1437,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
 
  give_sigsegv:
     unlock_user_struct(frame, frame_addr, 1);
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(usig);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -2441,7 +2462,7 @@ sigill_and_return:
 #endif
 sigsegv:
     unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -3033,7 +3054,7 @@ static void setup_frame(int sig, struct target_sigaction * ka,
     return;
 
 give_sigsegv:
-    force_sig(TARGET_SIGSEGV/*, current*/);
+    force_sigsegv(sig);
 }
 
 long do_sigreturn(CPUMIPSState *regs)
@@ -3142,7 +3163,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
 give_sigsegv:
     unlock_user_struct(frame, frame_addr, 1);
-    force_sig(TARGET_SIGSEGV/*, current*/);
+    force_sigsegv(sig);
 }
 
 long do_rt_sigreturn(CPUMIPSState *env)
@@ -3345,7 +3366,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 
 give_sigsegv:
     unlock_user_struct(frame, frame_addr, 1);
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -3405,7 +3426,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
 give_sigsegv:
     unlock_user_struct(frame, frame_addr, 1);
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 long do_sigreturn(CPUSH4State *regs)
@@ -3652,7 +3673,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     unlock_user_struct(frame, frame_addr, 1);
     return;
 badframe:
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -3822,7 +3843,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     unlock_user_struct(frame, frame_addr, 1);
     return;
 badframe:
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -4061,10 +4082,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
 give_sigsegv:
     unlock_user_struct(frame, frame_addr, 1);
-    if (sig == TARGET_SIGSEGV) {
-        ka->_sa_handler = TARGET_SIG_DFL;
-    }
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 long do_sigreturn(CPUOpenRISCState *env)
@@ -4245,7 +4263,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     return;
 
 give_sigsegv:
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -4300,7 +4318,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     return;
 
 give_sigsegv:
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 static int
@@ -4811,7 +4829,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 
 sigsegv:
     unlock_user_struct(frame, frame_addr, 1);
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -4906,7 +4924,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
 sigsegv:
     unlock_user_struct(rt_sf, rt_sf_addr, 1);
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 
 }
 
@@ -5155,7 +5173,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     return;
 
 give_sigsegv:
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
@@ -5294,7 +5312,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
 give_sigsegv:
     unlock_user_struct(frame, frame_addr, 1);
-    force_sig(TARGET_SIGSEGV);
+    force_sigsegv(sig);
 }
 
 long do_sigreturn(CPUM68KState *env)
@@ -5501,10 +5519,8 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 
     if (err) {
 give_sigsegv:
-        if (sig == TARGET_SIGSEGV) {
-            ka->_sa_handler = TARGET_SIG_DFL;
-        }
-        force_sig(TARGET_SIGSEGV);
+        force_sigsegv(sig);
+        return;
     }
 
     env->ir[IR_RA] = r26;
@@ -5558,10 +5574,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
 
     if (err) {
 give_sigsegv:
-        if (sig == TARGET_SIGSEGV) {
-            ka->_sa_handler = TARGET_SIG_DFL;
-        }
-        force_sig(TARGET_SIGSEGV);
+        force_sigsegv(sig);
+        return;
     }
 
     env->ir[IR_RA] = r26;
@@ -5758,10 +5772,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     return;
 
 give_sigsegv:
-    if (sig == TARGET_SIGSEGV) {
-        ka->_sa_handler = TARGET_SIG_DFL;
-    }
-    force_sig(TARGET_SIGSEGV /* , current */);
+    force_sigsegv(sig);
 }
 
 long do_rt_sigreturn(CPUTLGState *env)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 20/26] linux-user: ARM: Give SIGSEGV if signal frame setup fails
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (18 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 19/26] linux-user: SIGSEGV on signal entry need not be fatal riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 21/26] linux-user: SIGSEGV from sigreturn need not be fatal riku.voipio
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

The 32-bit ARM signal frame setup code was just bailing out
on error returns from lock_user_struct calls, without
generating the SIGSEGV that should happen here. Wire up
error return codes to call force_sigsegv().

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/signal.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 892b527..4383696 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -512,8 +512,7 @@ void signal_init(void)
     }
 }
 
-#if !((defined(TARGET_ARM) && !defined(TARGET_AARCH64)) ||              \
-      defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
+#if !(defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
 
 /* Force a SIGSEGV if we couldn't write to memory trying to set
  * up the signal frame. oldsig is the signal we were trying to handle
@@ -1789,7 +1788,7 @@ static void setup_frame_v1(int usig, struct target_sigaction *ka,
 
     trace_user_setup_frame(regs, frame_addr);
     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        return;
+        goto sigsegv;
     }
 
     setup_sigcontext(&frame->sc, regs, set->sig[0]);
@@ -1802,6 +1801,9 @@ static void setup_frame_v1(int usig, struct target_sigaction *ka,
                  frame_addr + offsetof(struct sigframe_v1, retcode));
 
     unlock_user_struct(frame, frame_addr, 1);
+    return;
+sigsegv:
+    force_sigsegv(usig);
 }
 
 static void setup_frame_v2(int usig, struct target_sigaction *ka,
@@ -1812,7 +1814,7 @@ static void setup_frame_v2(int usig, struct target_sigaction *ka,
 
     trace_user_setup_frame(regs, frame_addr);
     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        return;
+        goto sigsegv;
     }
 
     setup_sigframe_v2(&frame->uc, set, regs);
@@ -1821,6 +1823,9 @@ static void setup_frame_v2(int usig, struct target_sigaction *ka,
                  frame_addr + offsetof(struct sigframe_v2, retcode));
 
     unlock_user_struct(frame, frame_addr, 1);
+    return;
+sigsegv:
+    force_sigsegv(usig);
 }
 
 static void setup_frame(int usig, struct target_sigaction *ka,
@@ -1846,7 +1851,7 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
 
     trace_user_setup_rt_frame(env, frame_addr);
     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        return /* 1 */;
+        goto sigsegv;
     }
 
     info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);
@@ -1876,6 +1881,9 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
     env->regs[2] = uc_addr;
 
     unlock_user_struct(frame, frame_addr, 1);
+    return;
+sigsegv:
+    force_sigsegv(usig);
 }
 
 static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
@@ -1888,7 +1896,7 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
 
     trace_user_setup_rt_frame(env, frame_addr);
     if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
-        return /* 1 */;
+        goto sigsegv;
     }
 
     info_addr = frame_addr + offsetof(struct rt_sigframe_v2, info);
@@ -1904,6 +1912,9 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
     env->regs[2] = uc_addr;
 
     unlock_user_struct(frame, frame_addr, 1);
+    return;
+sigsegv:
+    force_sigsegv(usig);
 }
 
 static void setup_rt_frame(int usig, struct target_sigaction *ka,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 21/26] linux-user: SIGSEGV from sigreturn need not be fatal
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (19 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 20/26] linux-user: ARM: Give SIGSEGV if signal frame setup fails riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 22/26] linux-user: Implement force_sigsegv() via force_sig() riku.voipio
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

If the sigreturn syscall fails to read memory then this causes a
SIGSEGV, but this is not necessarily a fatal signal -- the guest
process can catch it.

We don't implement this correctly because the behaviour of QEMU's
force_sig() function has drifted away from the kernel function of the
same name -- ours now does "always do a guest core dump and abort
execution", whereas the kernel version simply forces the guest to
take a signal, which may or may not eventually cause a core dump.

Rename our force_sig() to dump_core_and_abort(), and provide a
force_sig() which acts more like the kernel version as the sigreturn
implementations expect it to.  Since force_sig() now returns, we must
update all the callsites to return -TARGET_QEMU_ESIGRETURN so that
the main loop doesn't change the guest registers before the signal
handler is invoked.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/signal.c | 81 +++++++++++++++++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 27 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 4383696..60fda18 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -512,6 +512,27 @@ void signal_init(void)
     }
 }
 
+#if !defined(TARGET_OPENRISC) && !defined(TARGET_UNICORE32) && \
+    !defined(TARGET_X86_64)
+/* Force a synchronously taken signal. The kernel force_sig() function
+ * also forces the signal to "not blocked, not ignored", but for QEMU
+ * that work is done in process_pending_signals().
+ */
+static void force_sig(int sig)
+{
+    CPUState *cpu = thread_cpu;
+    CPUArchState *env = cpu->env_ptr;
+    target_siginfo_t info;
+
+    info.si_signo = sig;
+    info.si_errno = 0;
+    info.si_code = TARGET_SI_KERNEL;
+    info._sifields._kill._pid = 0;
+    info._sifields._kill._uid = 0;
+    queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
+}
+#endif
+
 #if !(defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
 
 /* Force a SIGSEGV if we couldn't write to memory trying to set
@@ -526,7 +547,7 @@ static void force_sigsegv(int oldsig)
 
     if (oldsig == SIGSEGV) {
         /* Make sure we don't try to deliver the signal again; this will
-         * end up with handle_pending_signal() calling force_sig().
+         * end up with handle_pending_signal() calling dump_core_and_abort().
          */
         sigact_table[oldsig - 1]._sa_handler = TARGET_SIG_DFL;
     }
@@ -540,7 +561,7 @@ static void force_sigsegv(int oldsig)
 #endif
 
 /* abort execution with signal */
-static void QEMU_NORETURN force_sig(int target_sig)
+static void QEMU_NORETURN dump_core_and_abort(int target_sig)
 {
     CPUState *cpu = thread_cpu;
     CPUArchState *env = cpu->env_ptr;
@@ -1181,7 +1202,7 @@ long do_sigreturn(CPUX86State *env)
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUX86State *env)
@@ -1212,7 +1233,7 @@ long do_rt_sigreturn(CPUX86State *env)
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 #elif defined(TARGET_AARCH64)
@@ -1482,7 +1503,7 @@ long do_rt_sigreturn(CPUARMState *env)
  badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_sigreturn(CPUARMState *env)
@@ -2004,8 +2025,8 @@ static long do_sigreturn_v1(CPUARMState *env)
     return -TARGET_QEMU_ESIGRETURN;
 
 badframe:
-    force_sig(TARGET_SIGSEGV /* , current */);
-    return 0;
+    force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
@@ -2131,8 +2152,8 @@ static long do_sigreturn_v2(CPUARMState *env)
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
-    force_sig(TARGET_SIGSEGV /* , current */);
-    return 0;
+    force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_sigreturn(CPUARMState *env)
@@ -2185,8 +2206,8 @@ static long do_rt_sigreturn_v1(CPUARMState *env)
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
-    force_sig(TARGET_SIGSEGV /* , current */);
-    return 0;
+    force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 static long do_rt_sigreturn_v2(CPUARMState *env)
@@ -2218,8 +2239,8 @@ static long do_rt_sigreturn_v2(CPUARMState *env)
 
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
-    force_sig(TARGET_SIGSEGV /* , current */);
-    return 0;
+    force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUARMState *env)
@@ -2553,6 +2574,7 @@ long do_sigreturn(CPUSPARCState *env)
 segv_and_exit:
     unlock_user_struct(sf, sf_addr, 0);
     force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUSPARCState *env)
@@ -3110,8 +3132,8 @@ long do_sigreturn(CPUMIPSState *regs)
     return -TARGET_QEMU_ESIGRETURN;
 
 badframe:
-    force_sig(TARGET_SIGSEGV/*, current*/);
-    return 0;
+    force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 # endif /* O32 */
 
@@ -3207,8 +3229,8 @@ long do_rt_sigreturn(CPUMIPSState *env)
     return -TARGET_QEMU_ESIGRETURN;
 
 badframe:
-    force_sig(TARGET_SIGSEGV/*, current*/);
-    return 0;
+    force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 #elif defined(TARGET_SH4)
@@ -3474,7 +3496,7 @@ long do_sigreturn(CPUSH4State *regs)
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUSH4State *regs)
@@ -3506,7 +3528,7 @@ long do_rt_sigreturn(CPUSH4State *regs)
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 #elif defined(TARGET_MICROBLAZE)
 
@@ -3725,6 +3747,7 @@ long do_sigreturn(CPUMBState *env)
     return -TARGET_QEMU_ESIGRETURN;
 badframe:
     force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUMBState *env)
@@ -3892,6 +3915,7 @@ long do_sigreturn(CPUCRISState *env)
     return -TARGET_QEMU_ESIGRETURN;
 badframe:
     force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUCRISState *env)
@@ -4383,7 +4407,7 @@ long do_sigreturn(CPUS390XState *env)
 
 badframe:
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUS390XState *env)
@@ -4414,7 +4438,7 @@ long do_rt_sigreturn(CPUS390XState *env)
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 #elif defined(TARGET_PPC)
@@ -4973,7 +4997,7 @@ sigsegv:
     unlock_user_struct(sr, sr_addr, 1);
     unlock_user_struct(sc, sc_addr, 1);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 /* See arch/powerpc/kernel/signal_32.c.  */
@@ -5028,7 +5052,7 @@ long do_rt_sigreturn(CPUPPCState *env)
 sigsegv:
     unlock_user_struct(rt_sf, rt_sf_addr, 1);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 #elif defined(TARGET_M68K)
@@ -5358,7 +5382,7 @@ long do_sigreturn(CPUM68KState *env)
 
 badframe:
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUM68KState *env)
@@ -5391,7 +5415,7 @@ long do_rt_sigreturn(CPUM68KState *env)
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
-    return 0;
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 #elif defined(TARGET_ALPHA)
@@ -5620,6 +5644,7 @@ long do_sigreturn(CPUAlphaState *env)
 
 badframe:
     force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 long do_rt_sigreturn(CPUAlphaState *env)
@@ -5649,6 +5674,7 @@ long do_rt_sigreturn(CPUAlphaState *env)
 badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 #elif defined(TARGET_TILEGX)
@@ -5813,6 +5839,7 @@ long do_rt_sigreturn(CPUTLGState *env)
  badframe:
     unlock_user_struct(frame, frame_addr, 0);
     force_sig(TARGET_SIGSEGV);
+    return -TARGET_QEMU_ESIGRETURN;
 }
 
 #else
@@ -5879,12 +5906,12 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
                    sig != TARGET_SIGURG &&
                    sig != TARGET_SIGWINCH &&
                    sig != TARGET_SIGCONT) {
-            force_sig(sig);
+            dump_core_and_abort(sig);
         }
     } else if (handler == TARGET_SIG_IGN) {
         /* ignore sig */
     } else if (handler == TARGET_SIG_ERR) {
-        force_sig(sig);
+        dump_core_and_abort(sig);
     } else {
         /* compute the blocked signals during the handler execution */
         sigset_t *blocked_set;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 22/26] linux-user: Implement force_sigsegv() via force_sig()
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (20 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 21/26] linux-user: SIGSEGV from sigreturn need not be fatal riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 23/26] linux-user: Remove unnecessary nptl_flags variable from do_fork() riku.voipio
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

Now that we have a force_sig() with the semantics we need,
we can implement force_sigsegv() to call it rather than
open-coding the call to queue_signal().

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/signal.c | 17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 60fda18..900ee35 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -512,8 +512,7 @@ void signal_init(void)
     }
 }
 
-#if !defined(TARGET_OPENRISC) && !defined(TARGET_UNICORE32) && \
-    !defined(TARGET_X86_64)
+#if !(defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
 /* Force a synchronously taken signal. The kernel force_sig() function
  * also forces the signal to "not blocked, not ignored", but for QEMU
  * that work is done in process_pending_signals().
@@ -531,9 +530,6 @@ static void force_sig(int sig)
     info._sifields._kill._uid = 0;
     queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
 }
-#endif
-
-#if !(defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
 
 /* Force a SIGSEGV if we couldn't write to memory trying to set
  * up the signal frame. oldsig is the signal we were trying to handle
@@ -541,22 +537,13 @@ static void force_sig(int sig)
  */
 static void force_sigsegv(int oldsig)
 {
-    CPUState *cpu = thread_cpu;
-    CPUArchState *env = cpu->env_ptr;
-    target_siginfo_t info;
-
     if (oldsig == SIGSEGV) {
         /* Make sure we don't try to deliver the signal again; this will
          * end up with handle_pending_signal() calling dump_core_and_abort().
          */
         sigact_table[oldsig - 1]._sa_handler = TARGET_SIG_DFL;
     }
-    info.si_signo = TARGET_SIGSEGV;
-    info.si_errno = 0;
-    info.si_code = TARGET_SI_KERNEL;
-    info._sifields._kill._pid = 0;
-    info._sifields._kill._uid = 0;
-    queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
+    force_sig(TARGET_SIGSEGV);
 }
 #endif
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 23/26] linux-user: Remove unnecessary nptl_flags variable from do_fork()
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (21 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 22/26] linux-user: Implement force_sigsegv() via force_sig() riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 24/26] linux-user: Sanity check clone flags riku.voipio
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

The 'nptl_flags' variable in do_fork() is set to a copy of
'flags', and then the CLONE_NPTL_FLAGS are cleared out of 'flags'.
However the only effect of this is that the later check on
"if (flags & CLONE_PARENT_SETTID)" is never true. Since we
will already have done the setting of parent_tidptr in clone_func()
in the child thread, we don't need to do it again.

Delete the dead if() and the clearing of CLONE_NPTL_FLAGS from
'flags', and then use 'flags' where we were previously using
'nptl_flags', so we can delete the unnecessary variable.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 27ad6a2..3b7b51f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6011,7 +6011,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
     TaskState *ts;
     CPUState *new_cpu;
     CPUArchState *new_env;
-    unsigned int nptl_flags;
     sigset_t sigmask;
 
     /* Emulate vfork() with fork() */
@@ -6034,15 +6033,14 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         ts->bprm = parent_ts->bprm;
         ts->info = parent_ts->info;
         ts->signal_mask = parent_ts->signal_mask;
-        nptl_flags = flags;
-        flags &= ~CLONE_NPTL_FLAGS2;
 
-        if (nptl_flags & CLONE_CHILD_CLEARTID) {
+        if (flags & CLONE_CHILD_CLEARTID) {
             ts->child_tidptr = child_tidptr;
         }
 
-        if (nptl_flags & CLONE_SETTLS)
+        if (flags & CLONE_SETTLS) {
             cpu_set_tls (new_env, newtls);
+        }
 
         /* Grab a mutex so that thread setup appears atomic.  */
         pthread_mutex_lock(&clone_lock);
@@ -6052,10 +6050,12 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         pthread_mutex_lock(&info.mutex);
         pthread_cond_init(&info.cond, NULL);
         info.env = new_env;
-        if (nptl_flags & CLONE_CHILD_SETTID)
+        if (flags & CLONE_CHILD_SETTID) {
             info.child_tidptr = child_tidptr;
-        if (nptl_flags & CLONE_PARENT_SETTID)
+        }
+        if (flags & CLONE_PARENT_SETTID) {
             info.parent_tidptr = parent_tidptr;
+        }
 
         ret = pthread_attr_init(&attr);
         ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
@@ -6074,8 +6074,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
             /* Wait for the child to initialize.  */
             pthread_cond_wait(&info.cond, &info.mutex);
             ret = info.tid;
-            if (flags & CLONE_PARENT_SETTID)
-                put_user_u32(ret, parent_tidptr);
         } else {
             ret = -1;
         }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 24/26] linux-user: Sanity check clone flags
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (22 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 23/26] linux-user: Remove unnecessary nptl_flags variable from do_fork() riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 25/26] linux-user: Fix incorrect offset of tuc_stack in ARM do_sigframe_return_v2 riku.voipio
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell

From: Peter Maydell <peter.maydell@linaro.org>

We currently make no checks on the flags passed to the clone syscall,
which means we will not fail clone attempts which ask for features
that we can't implement. Add sanity checking of the flags to clone
(which we were already doing in the "this is a fork" path, but not
for the "this is a new thread" path), tidy up the checking in
the fork path to match it, and check that the fork case isn't trying
to specify a custom termination signal.

This is helpful in causing some LTP test cases to fail cleanly
rather than behaving bizarrely when we let the clone succeed
but didn't provide the semantics requested by the flags.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 3 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3b7b51f..d7e4d9f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -112,8 +112,56 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 
 #include "qemu.h"
 
-#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
-    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
+#ifndef CLONE_IO
+#define CLONE_IO                0x80000000      /* Clone io context */
+#endif
+
+/* We can't directly call the host clone syscall, because this will
+ * badly confuse libc (breaking mutexes, for example). So we must
+ * divide clone flags into:
+ *  * flag combinations that look like pthread_create()
+ *  * flag combinations that look like fork()
+ *  * flags we can implement within QEMU itself
+ *  * flags we can't support and will return an error for
+ */
+/* For thread creation, all these flags must be present; for
+ * fork, none must be present.
+ */
+#define CLONE_THREAD_FLAGS                              \
+    (CLONE_VM | CLONE_FS | CLONE_FILES |                \
+     CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM)
+
+/* These flags are ignored:
+ * CLONE_DETACHED is now ignored by the kernel;
+ * CLONE_IO is just an optimisation hint to the I/O scheduler
+ */
+#define CLONE_IGNORED_FLAGS                     \
+    (CLONE_DETACHED | CLONE_IO)
+
+/* Flags for fork which we can implement within QEMU itself */
+#define CLONE_OPTIONAL_FORK_FLAGS               \
+    (CLONE_SETTLS | CLONE_PARENT_SETTID |       \
+     CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID)
+
+/* Flags for thread creation which we can implement within QEMU itself */
+#define CLONE_OPTIONAL_THREAD_FLAGS                             \
+    (CLONE_SETTLS | CLONE_PARENT_SETTID |                       \
+     CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT)
+
+#define CLONE_INVALID_FORK_FLAGS                                        \
+    (~(CSIGNAL | CLONE_OPTIONAL_FORK_FLAGS | CLONE_IGNORED_FLAGS))
+
+#define CLONE_INVALID_THREAD_FLAGS                                      \
+    (~(CSIGNAL | CLONE_THREAD_FLAGS | CLONE_OPTIONAL_THREAD_FLAGS |     \
+       CLONE_IGNORED_FLAGS))
+
+/* CLONE_VFORK is special cased early in do_fork(). The other flag bits
+ * have almost all been allocated. We cannot support any of
+ * CLONE_NEWNS, CLONE_NEWCGROUP, CLONE_NEWUTS, CLONE_NEWIPC,
+ * CLONE_NEWUSER, CLONE_NEWPID, CLONE_NEWNET, CLONE_PTRACE, CLONE_UNTRACED.
+ * The checks against the invalid thread masks above will catch these.
+ * (The one remaining unallocated bit is 0x1000 which used to be CLONE_PID.)
+ */
 
 //#define DEBUG
 /* Define DEBUG_ERESTARTSYS to force every syscall to be restarted
@@ -6013,6 +6061,8 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
     CPUArchState *new_env;
     sigset_t sigmask;
 
+    flags &= ~CLONE_IGNORED_FLAGS;
+
     /* Emulate vfork() with fork() */
     if (flags & CLONE_VFORK)
         flags &= ~(CLONE_VFORK | CLONE_VM);
@@ -6022,6 +6072,11 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         new_thread_info info;
         pthread_attr_t attr;
 
+        if (((flags & CLONE_THREAD_FLAGS) != CLONE_THREAD_FLAGS) ||
+            (flags & CLONE_INVALID_THREAD_FLAGS)) {
+            return -TARGET_EINVAL;
+        }
+
         ts = g_new0(TaskState, 1);
         init_task_state(ts);
         /* we create a new CPU instance. */
@@ -6083,7 +6138,12 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         pthread_mutex_unlock(&clone_lock);
     } else {
         /* if no CLONE_VM, we consider it is a fork */
-        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) {
+        if (flags & CLONE_INVALID_FORK_FLAGS) {
+            return -TARGET_EINVAL;
+        }
+
+        /* We can't support custom termination signals */
+        if ((flags & CSIGNAL) != TARGET_SIGCHLD) {
             return -TARGET_EINVAL;
         }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 25/26] linux-user: Fix incorrect offset of tuc_stack in ARM do_sigframe_return_v2
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (23 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 24/26] linux-user: Sanity check clone flags riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 12:13 ` [Qemu-devel] [PULL 26/26] linux-user: fix TARGET_NR_select riku.voipio
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Timothy E Baldwin

From: Timothy E Baldwin <T.E.Baldwin99@members.leeds.ac.uk>

struct target_ucontext_v2 is not at the begining of the signal frame,
therefore do_sigaltstack was being passed bogus arguments.

As the offset depends on the type of signal frame fixed by passing in the
beginning of the context from do_sigreturn_v2 and do_rt_sigreturn_v2.

Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/signal.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 900ee35..e4eea69 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2071,7 +2071,8 @@ static abi_ulong *restore_sigframe_v2_iwmmxt(CPUARMState *env,
     return (abi_ulong*)(iwmmxtframe + 1);
 }
 
-static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
+static int do_sigframe_return_v2(CPUARMState *env,
+                                 target_ulong context_addr,
                                  struct target_ucontext_v2 *uc)
 {
     sigset_t host_set;
@@ -2098,8 +2099,11 @@ static int do_sigframe_return_v2(CPUARMState *env, target_ulong frame_addr,
         }
     }
 
-    if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
+    if (do_sigaltstack(context_addr
+                       + offsetof(struct target_ucontext_v2, tuc_stack),
+                       0, get_sp_from_cpustate(env)) == -EFAULT) {
         return 1;
+    }
 
 #if 0
     /* Send SIGTRAP if we're single-stepping */
@@ -2130,7 +2134,10 @@ static long do_sigreturn_v2(CPUARMState *env)
         goto badframe;
     }
 
-    if (do_sigframe_return_v2(env, frame_addr, &frame->uc)) {
+    if (do_sigframe_return_v2(env,
+                              frame_addr
+                              + offsetof(struct sigframe_v2, uc),
+                              &frame->uc)) {
         goto badframe;
     }
 
@@ -2217,7 +2224,10 @@ static long do_rt_sigreturn_v2(CPUARMState *env)
         goto badframe;
     }
 
-    if (do_sigframe_return_v2(env, frame_addr, &frame->uc)) {
+    if (do_sigframe_return_v2(env,
+                              frame_addr
+                              + offsetof(struct rt_sigframe_v2, uc),
+                              &frame->uc)) {
         goto badframe;
     }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PULL 26/26] linux-user: fix TARGET_NR_select
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (24 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 25/26] linux-user: Fix incorrect offset of tuc_stack in ARM do_sigframe_return_v2 riku.voipio
@ 2016-09-22 12:13 ` riku.voipio
  2016-09-22 13:07 ` [Qemu-devel] [PULL 00/26] linux-user update no-reply
  2016-09-22 15:42 ` Peter Maydell
  27 siblings, 0 replies; 29+ messages in thread
From: riku.voipio @ 2016-09-22 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Laurent Vivier

From: Laurent Vivier <laurent@vivier.eu>

TARGET_NR_select can have three different implementations:

  1- to always return -ENOSYS

     microblaze, ppc, ppc64

     -> TARGET_WANT_NI_OLD_SELECT

  2- to take parameters from a structure pointed by arg1
    (kernel sys_old_select)

     i386, arm, m68k

     -> TARGET_WANT_OLD_SYS_SELECT

  3- to take parameters from arg[1-5]
     (kernel sys_select)

     x86_64, alpha, s390x,
     cris, sparc, sparc64

Some (new) architectures don't define NR_select,

  4- but only NR__newselect with sys_select:

      mips, mips64, sh

  5- don't define NR__newselect, and use pselect6 syscall:

      aarch64, openrisc, tilegx, unicore32

Reported-by: Timothy Pearson <tpearson@raptorengineering.com>
Reported-by: Allan Wirth <awirth@akamai.com>
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/arm/target_syscall.h        |  1 +
 linux-user/i386/target_syscall.h       |  1 +
 linux-user/m68k/target_syscall.h       |  2 ++
 linux-user/microblaze/target_syscall.h |  2 ++
 linux-user/openrisc/syscall_nr.h       |  2 --
 linux-user/ppc/target_syscall.h        |  1 +
 linux-user/sh4/syscall_nr.h            |  2 +-
 linux-user/syscall.c                   | 48 ++++++++++++++++++++++------------
 linux-user/tilegx/syscall_nr.h         |  1 -
 9 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/linux-user/arm/target_syscall.h b/linux-user/arm/target_syscall.h
index 0879b4d..94e2a42 100644
--- a/linux-user/arm/target_syscall.h
+++ b/linux-user/arm/target_syscall.h
@@ -32,6 +32,7 @@ struct target_pt_regs {
 #define TARGET_MINSIGSTKSZ 2048
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
+#define TARGET_WANT_OLD_SYS_SELECT
 
 #define TARGET_FORCE_SHMLBA
 
diff --git a/linux-user/i386/target_syscall.h b/linux-user/i386/target_syscall.h
index b4e895f..2854758 100644
--- a/linux-user/i386/target_syscall.h
+++ b/linux-user/i386/target_syscall.h
@@ -153,5 +153,6 @@ struct target_vm86plus_struct {
 #define TARGET_MINSIGSTKSZ 2048
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
+#define TARGET_WANT_OLD_SYS_SELECT
 
 #endif /* I386_TARGET_SYSCALL_H */
diff --git a/linux-user/m68k/target_syscall.h b/linux-user/m68k/target_syscall.h
index db2be4f..632ee4f 100644
--- a/linux-user/m68k/target_syscall.h
+++ b/linux-user/m68k/target_syscall.h
@@ -24,6 +24,8 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
+#define TARGET_WANT_OLD_SYS_SELECT
+
 void do_m68k_simcall(CPUM68KState *, int);
 
 #endif /* M68K_TARGET_SYSCALL_H */
diff --git a/linux-user/microblaze/target_syscall.h b/linux-user/microblaze/target_syscall.h
index 0b6980c..4141cba 100644
--- a/linux-user/microblaze/target_syscall.h
+++ b/linux-user/microblaze/target_syscall.h
@@ -53,4 +53,6 @@ struct target_pt_regs {
 #define TARGET_MLOCKALL_MCL_CURRENT 1
 #define TARGET_MLOCKALL_MCL_FUTURE  2
 
+#define TARGET_WANT_NI_OLD_SELECT
+
 #endif
diff --git a/linux-user/openrisc/syscall_nr.h b/linux-user/openrisc/syscall_nr.h
index 6b1c7d2..04059d0 100644
--- a/linux-user/openrisc/syscall_nr.h
+++ b/linux-user/openrisc/syscall_nr.h
@@ -459,8 +459,6 @@
 #define TARGET_NR_getdents 1065
 #define __ARCH_WANT_SYS_GETDENTS
 #define TARGET_NR_futimesat 1066
-#define TARGET_NR_select 1067
-#define __ARCH_WANT_SYS_SELECT
 #define TARGET_NR_poll 1068
 #define TARGET_NR_epoll_wait 1069
 #define TARGET_NR_ustat 1070
diff --git a/linux-user/ppc/target_syscall.h b/linux-user/ppc/target_syscall.h
index a8662f4..afc0570 100644
--- a/linux-user/ppc/target_syscall.h
+++ b/linux-user/ppc/target_syscall.h
@@ -74,5 +74,6 @@ struct target_revectored_struct {
 #define TARGET_MINSIGSTKSZ 2048
 #define TARGET_MLOCKALL_MCL_CURRENT 0x2000
 #define TARGET_MLOCKALL_MCL_FUTURE  0x4000
+#define TARGET_WANT_NI_OLD_SELECT
 
 #endif /* PPC_TARGET_SYSCALL_H */
diff --git a/linux-user/sh4/syscall_nr.h b/linux-user/sh4/syscall_nr.h
index 5009984..e99f735 100644
--- a/linux-user/sh4/syscall_nr.h
+++ b/linux-user/sh4/syscall_nr.h
@@ -84,7 +84,7 @@
 #define TARGET_NR_settimeofday	 79
 #define TARGET_NR_getgroups		 80
 #define TARGET_NR_setgroups		 81
-#define TARGET_NR_select		 82
+                                         /* 82 was sys_oldselect */
 #define TARGET_NR_symlink		 83
 #define TARGET_NR_oldlstat		 84
 #define TARGET_NR_readlink		 85
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d7e4d9f..7aa2c1d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1444,6 +1444,29 @@ static abi_long do_select(int n,
 
     return ret;
 }
+
+#if defined(TARGET_WANT_OLD_SYS_SELECT)
+static abi_long do_old_select(abi_ulong arg1)
+{
+    struct target_sel_arg_struct *sel;
+    abi_ulong inp, outp, exp, tvp;
+    long nsel;
+
+    if (!lock_user_struct(VERIFY_READ, sel, arg1, 1)) {
+        return -TARGET_EFAULT;
+    }
+
+    nsel = tswapal(sel->n);
+    inp = tswapal(sel->inp);
+    outp = tswapal(sel->outp);
+    exp = tswapal(sel->exp);
+    tvp = tswapal(sel->tvp);
+
+    unlock_user_struct(sel, arg1, 0);
+
+    return do_select(nsel, inp, outp, exp, tvp);
+}
+#endif
 #endif
 
 static abi_long do_pipe2(int host_pipe[], int flags)
@@ -8668,24 +8691,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #if defined(TARGET_NR_select)
     case TARGET_NR_select:
-#if defined(TARGET_S390X) || defined(TARGET_ALPHA)
-        ret = do_select(arg1, arg2, arg3, arg4, arg5);
+#if defined(TARGET_WANT_NI_OLD_SELECT)
+        /* some architectures used to have old_select here
+         * but now ENOSYS it.
+         */
+        ret = -TARGET_ENOSYS;
+#elif defined(TARGET_WANT_OLD_SYS_SELECT)
+        ret = do_old_select(arg1);
 #else
-        {
-            struct target_sel_arg_struct *sel;
-            abi_ulong inp, outp, exp, tvp;
-            long nsel;
-
-            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
-                goto efault;
-            nsel = tswapal(sel->n);
-            inp = tswapal(sel->inp);
-            outp = tswapal(sel->outp);
-            exp = tswapal(sel->exp);
-            tvp = tswapal(sel->tvp);
-            unlock_user_struct(sel, arg1, 0);
-            ret = do_select(nsel, inp, outp, exp, tvp);
-        }
+        ret = do_select(arg1, arg2, arg3, arg4, arg5);
 #endif
         break;
 #endif
diff --git a/linux-user/tilegx/syscall_nr.h b/linux-user/tilegx/syscall_nr.h
index 8e30cd1..c104b94 100644
--- a/linux-user/tilegx/syscall_nr.h
+++ b/linux-user/tilegx/syscall_nr.h
@@ -311,7 +311,6 @@
 #define TARGET_NR_creat                         1064
 #define TARGET_NR_getdents                      1065
 #define TARGET_NR_futimesat                     1066
-#define TARGET_NR_select                        1067
 #define TARGET_NR_poll                          1068
 #define TARGET_NR_epoll_wait                    1069
 #define TARGET_NR_ustat                         1070
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PULL 00/26] linux-user update
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (25 preceding siblings ...)
  2016-09-22 12:13 ` [Qemu-devel] [PULL 26/26] linux-user: fix TARGET_NR_select riku.voipio
@ 2016-09-22 13:07 ` no-reply
  2016-09-22 15:42 ` Peter Maydell
  27 siblings, 0 replies; 29+ messages in thread
From: no-reply @ 2016-09-22 13:07 UTC (permalink / raw)
  To: riku.voipio; +Cc: famz, qemu-devel, peter.maydell

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: cover.1474546244.git.riku.voipio@linaro.org
Subject: [Qemu-devel] [PULL 00/26] linux-user update

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git show --no-patch --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
c530452 linux-user: fix TARGET_NR_select
c96fe2f linux-user: Fix incorrect offset of tuc_stack in ARM do_sigframe_return_v2
b593958 linux-user: Sanity check clone flags
153487c linux-user: Remove unnecessary nptl_flags variable from do_fork()
401280d linux-user: Implement force_sigsegv() via force_sig()
f4521bb linux-user: SIGSEGV from sigreturn need not be fatal
6d101e2 linux-user: ARM: Give SIGSEGV if signal frame setup fails
5216a3a linux-user: SIGSEGV on signal entry need not be fatal
1bfdef8 linux-user: Pass si_type information to queue_signal() explicitly
5703d87 linux-user: Recheck for pending synchronous signals too
34fc16a linux-user: ppc64: set MSR_CM bit for BookE 2.06 MMU
febbc63 linux-user: Use correct target SHMLBA in shmat()
894d8ae linux-user: Use glib malloc functions in load_symbols()
0181e3e linux-user: Check dump_write() return in elf_core_dump()
95f7091 linux-user: Fix error handling in flatload.c target_pread()
07748da linux-user: Fix incorrect use of host errno in do_ioctl_dm()
03f4c78 linux-user: Check lock_user() return value for NULL
d3d5c63 linux-user: Pass missing MAP_ANONYMOUS to target_mmap() call
e3b270d linux-user: report signals being taken in strace output
bce0802 linux-user: Range check the nfds argument to ppoll syscall
96e1e0e linux-user: Check for bad event numbers in epoll_wait
caba33f linux-user: Use direct syscall for utimensat
4050f40 linux-user: Implement FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls
a291b03 linux-user: Allow bad msg_name for recvfrom on connected socket
97a5a62 linux-user: Fix errno for sendrecvmsg with large iovec length
63b346f linux-user: Fix handling of iovec counts

=== OUTPUT BEGIN ===
Checking PATCH 1/26: linux-user: Fix handling of iovec counts...
Checking PATCH 2/26: linux-user: Fix errno for sendrecvmsg with large iovec length...
Checking PATCH 3/26: linux-user: Allow bad msg_name for recvfrom on connected socket...
Checking PATCH 4/26: linux-user: Implement FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls...
Checking PATCH 5/26: linux-user: Use direct syscall for utimensat...
ERROR: architecture specific defines should be avoided
#42: FILE: linux-user/syscall.c:523:
+#if defined(__NR_utimensat)

total: 1 errors, 0 warnings, 17 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 6/26: linux-user: Check for bad event numbers in epoll_wait...
Checking PATCH 7/26: linux-user: Range check the nfds argument to ppoll syscall...
Checking PATCH 8/26: linux-user: report signals being taken in strace output...
Checking PATCH 9/26: linux-user: Pass missing MAP_ANONYMOUS to target_mmap() call...
Checking PATCH 10/26: linux-user: Check lock_user() return value for NULL...
Checking PATCH 11/26: linux-user: Fix incorrect use of host errno in do_ioctl_dm()...
Checking PATCH 12/26: linux-user: Fix error handling in flatload.c target_pread()...
Checking PATCH 13/26: linux-user: Check dump_write() return in elf_core_dump()...
Checking PATCH 14/26: linux-user: Use glib malloc functions in load_symbols()...
Checking PATCH 15/26: linux-user: Use correct target SHMLBA in shmat()...
Checking PATCH 16/26: linux-user: ppc64: set MSR_CM bit for BookE 2.06 MMU...
Checking PATCH 17/26: linux-user: Recheck for pending synchronous signals too...
Checking PATCH 18/26: linux-user: Pass si_type information to queue_signal() explicitly...
Checking PATCH 19/26: linux-user: SIGSEGV on signal entry need not be fatal...
Checking PATCH 20/26: linux-user: ARM: Give SIGSEGV if signal frame setup fails...
Checking PATCH 21/26: linux-user: SIGSEGV from sigreturn need not be fatal...
Checking PATCH 22/26: linux-user: Implement force_sigsegv() via force_sig()...
Checking PATCH 23/26: linux-user: Remove unnecessary nptl_flags variable from do_fork()...
Checking PATCH 24/26: linux-user: Sanity check clone flags...
Checking PATCH 25/26: linux-user: Fix incorrect offset of tuc_stack in ARM do_sigframe_return_v2...
Checking PATCH 26/26: linux-user: fix TARGET_NR_select...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PULL 00/26] linux-user update
  2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
                   ` (26 preceding siblings ...)
  2016-09-22 13:07 ` [Qemu-devel] [PULL 00/26] linux-user update no-reply
@ 2016-09-22 15:42 ` Peter Maydell
  27 siblings, 0 replies; 29+ messages in thread
From: Peter Maydell @ 2016-09-22 15:42 UTC (permalink / raw)
  To: Riku Voipio; +Cc: QEMU Developers

On 22 September 2016 at 13:13,  <riku.voipio@linaro.org> wrote:
> From: Riku Voipio <riku.voipio@linaro.org>
>
> The following changes since commit a008535b9fa396226ff9cf78b8ac5f3584bda58e:
>
>   build-sys: fix make install regression (2016-09-20 11:32:43 +0100)
>
> are available in the git repository at:
>
>   git://git.linaro.org/people/riku.voipio/qemu.git tags/pull-linux-user-20160915
>
> for you to fetch changes up to 5457dc9e37fe0a29989bd64306c63941074864ce:
>
>   linux-user: fix TARGET_NR_select (2016-09-22 07:24:21 +0300)
>
> ----------------------------------------------------------------
> linux-user changes since 2.7 release

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2016-09-22 15:43 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-22 12:13 [Qemu-devel] [PULL 00/26] linux-user update riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 01/26] linux-user: Fix handling of iovec counts riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 02/26] linux-user: Fix errno for sendrecvmsg with large iovec length riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 03/26] linux-user: Allow bad msg_name for recvfrom on connected socket riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 04/26] linux-user: Implement FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 05/26] linux-user: Use direct syscall for utimensat riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 06/26] linux-user: Check for bad event numbers in epoll_wait riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 07/26] linux-user: Range check the nfds argument to ppoll syscall riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 08/26] linux-user: report signals being taken in strace output riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 09/26] linux-user: Pass missing MAP_ANONYMOUS to target_mmap() call riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 10/26] linux-user: Check lock_user() return value for NULL riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 11/26] linux-user: Fix incorrect use of host errno in do_ioctl_dm() riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 12/26] linux-user: Fix error handling in flatload.c target_pread() riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 13/26] linux-user: Check dump_write() return in elf_core_dump() riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 14/26] linux-user: Use glib malloc functions in load_symbols() riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 15/26] linux-user: Use correct target SHMLBA in shmat() riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 16/26] linux-user: ppc64: set MSR_CM bit for BookE 2.06 MMU riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 17/26] linux-user: Recheck for pending synchronous signals too riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 18/26] linux-user: Pass si_type information to queue_signal() explicitly riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 19/26] linux-user: SIGSEGV on signal entry need not be fatal riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 20/26] linux-user: ARM: Give SIGSEGV if signal frame setup fails riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 21/26] linux-user: SIGSEGV from sigreturn need not be fatal riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 22/26] linux-user: Implement force_sigsegv() via force_sig() riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 23/26] linux-user: Remove unnecessary nptl_flags variable from do_fork() riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 24/26] linux-user: Sanity check clone flags riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 25/26] linux-user: Fix incorrect offset of tuc_stack in ARM do_sigframe_return_v2 riku.voipio
2016-09-22 12:13 ` [Qemu-devel] [PULL 26/26] linux-user: fix TARGET_NR_select riku.voipio
2016-09-22 13:07 ` [Qemu-devel] [PULL 00/26] linux-user update no-reply
2016-09-22 15:42 ` Peter Maydell

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.