All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power
@ 2014-08-04 16:45 Tom Musta
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 01/12] linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2 Tom Musta
                   ` (12 more replies)
  0 siblings, 13 replies; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

This series of patches is the result of executing the Linux Test Program
(LTP) System Call bucket (https://github.com/linux-test-project/ltp)
on the 64 bit big and little endian linux user mode targets for Power.

Some of the changes are not technically unique to Power, but are effectively
so.  For example, Power may be the only runtime that uses the ipc system call
as a hub for other system calls (semctl, semop, ...).

The series is dependent on my previous patch series that adds signal handler
support on PPC64 (http://lists.nongnu.org/archive/html/qemu-ppc/2014-06/msg00802.html).
That series has gone into Alex's ppcnext branch for QEMU 2.2.

Tom Musta (12):
  linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2
  linux-user: Dereference Pointer Argument to ipc/semctl Sys Call
  linux-user: Properly Handle semun Structure In Cross-Endian
    Situations
  linux-user: Make ipc syscall's third argument an abi_long
  linux-user: Conditionally Pass Attribute Pointer to mq_open()
  linux-user: Detect Negative Message Sizes in msgsnd System Call
  linux-user: Handle NULL argument to sched_{get,set}param
  linux-user: Detect fault in sched_rr_get_interval
  linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2
  linux-user: clock_nanosleep errno Handling on PPC
  linux-user: Support target-to-host translation of mlockall argument
  linux-user: writev Partial Writes

 linux-user/signal.c  |   12 +++++-
 linux-user/syscall.c |  113 ++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 107 insertions(+), 18 deletions(-)

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

* [Qemu-devel] [PATCH 01/12] linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 02/12] linux-user: Dereference Pointer Argument to ipc/semctl Sys Call Tom Musta
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

The 64 bit PowerPC platforms eliminate the _unused1 and _unused2
elements of the semid_ds structure from <sys/sem.h>.  So eliminate
these from the target_semid_ds structure.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index a50229d..540001c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2419,9 +2419,13 @@ struct target_semid_ds
 {
   struct target_ipc_perm sem_perm;
   abi_ulong sem_otime;
+#if !defined(TARGET_PPC64)
   abi_ulong __unused1;
+#endif
   abi_ulong sem_ctime;
+#if !defined(TARGET_PPC64)
   abi_ulong __unused2;
+#endif
   abi_ulong sem_nsems;
   abi_ulong __unused3;
   abi_ulong __unused4;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 02/12] linux-user: Dereference Pointer Argument to ipc/semctl Sys Call
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 01/12] linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2 Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:04   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 03/12] linux-user: Properly Handle semun Structure In Cross-Endian Situations Tom Musta
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

When the ipc system call is used to wrap a semctl system call,
the ptr argument to ipc needs to be dereferenced prior to passing
it to the semctl handler.  This is because the fourth argument to
semctl is a union and not a pointer to a union.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 540001c..229c482 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3135,9 +3135,15 @@ static abi_long do_ipc(unsigned int call, int first,
         ret = get_errno(semget(first, second, third));
         break;
 
-    case IPCOP_semctl:
-        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
+    case IPCOP_semctl: {
+        /* The semun argument to semctl is passed by value, so dereference the
+         * ptr argument. */
+        abi_ulong atptr;
+        get_user_ual(atptr, (abi_ulong)ptr);
+        ret = do_semctl(first, second, third,
+                (union target_semun)(abi_ulong) atptr);
         break;
+    }
 
     case IPCOP_msgget:
         ret = get_errno(msgget(first, second));
-- 
1.7.1

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

* [Qemu-devel] [PATCH 03/12] linux-user: Properly Handle semun Structure In Cross-Endian Situations
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 01/12] linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2 Tom Musta
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 02/12] linux-user: Dereference Pointer Argument to ipc/semctl Sys Call Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:23   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 04/12] linux-user: Make ipc syscall's third argument an abi_long Tom Musta
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

The semun union used in the semctl system call contains both an int (val) and
pointers.  In cross-endian situations on 64 bit targets, the target memory
must be byte swapped, otherwise the wrong 32 bits are used for the val
field.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 229c482..fb03e96 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2647,9 +2647,14 @@ static inline abi_long do_semctl(int semid, int semnum, int cmd,
     switch( cmd ) {
 	case GETVAL:
 	case SETVAL:
+#if TARGET_ABI_BITS == 64
+            /* In 64 bit cross endian situations, we will erroneously pick up
+             * the wrong half of the union for the "val" element.  To rectify
+             * this, the entire structure is byteswaped. */
+            target_su.buf = tswapal(target_su.buf);
+#endif
             arg.val = tswap32(target_su.val);
             ret = get_errno(semctl(semid, semnum, cmd, arg));
-            target_su.val = tswap32(arg.val);
             break;
 	case GETALL:
 	case SETALL:
-- 
1.7.1

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

* [Qemu-devel] [PATCH 04/12] linux-user: Make ipc syscall's third argument an abi_long
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (2 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 03/12] linux-user: Properly Handle semun Structure In Cross-Endian Situations Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:09   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 05/12] linux-user: Conditionally Pass Attribute Pointer to mq_open() Tom Musta
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

For those target ABIs that use the ipc system call (e.g. POWER),
the third argument is used in the shmat path as a pointer.  It
therefore must be declared as an abi_long (versus int) so that
the address bits are not lost in truncation.  The "int-ness" of
this argument is retained for all other system calls via an
explicit cast.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fb03e96..bf6dd1e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3122,7 +3122,7 @@ static inline abi_long do_shmdt(abi_ulong shmaddr)
 /* ??? This only works with linear mappings.  */
 /* do_ipc() must return target values and target errnos. */
 static abi_long do_ipc(unsigned int call, int first,
-                       int second, int third,
+                       int second, abi_long third,
                        abi_long ptr, abi_long fifth)
 {
     int version;
@@ -3137,7 +3137,7 @@ static abi_long do_ipc(unsigned int call, int first,
         break;
 
     case IPCOP_semget:
-        ret = get_errno(semget(first, second, third));
+        ret = get_errno(semget(first, second, (int)third));
         break;
 
     case IPCOP_semctl: {
@@ -3145,7 +3145,7 @@ static abi_long do_ipc(unsigned int call, int first,
          * ptr argument. */
         abi_ulong atptr;
         get_user_ual(atptr, (abi_ulong)ptr);
-        ret = do_semctl(first, second, third,
+        ret = do_semctl(first, second, (int)third,
                 (union target_semun)(abi_ulong) atptr);
         break;
     }
@@ -3155,7 +3155,7 @@ static abi_long do_ipc(unsigned int call, int first,
         break;
 
     case IPCOP_msgsnd:
-        ret = do_msgsnd(first, ptr, second, third);
+        ret = do_msgsnd(first, ptr, second, (int)third);
         break;
 
     case IPCOP_msgctl:
@@ -3176,13 +3176,14 @@ static abi_long do_ipc(unsigned int call, int first,
                     break;
                 }
 
-                ret = do_msgrcv(first, tswapal(tmp->msgp), second, tswapal(tmp->msgtyp), third);
+                ret = do_msgrcv(first, tswapal(tmp->msgp), second,
+                                tswapal(tmp->msgtyp), (int)third);
 
                 unlock_user_struct(tmp, ptr, 0);
                 break;
             }
         default:
-            ret = do_msgrcv(first, ptr, second, fifth, third);
+            ret = do_msgrcv(first, ptr, second, fifth, (int)third);
         }
         break;
 
@@ -3209,7 +3210,7 @@ static abi_long do_ipc(unsigned int call, int first,
 
     case IPCOP_shmget:
 	/* IPC_* flag values are the same on all linux platforms */
-	ret = get_errno(shmget(first, second, third));
+        ret = get_errno(shmget(first, second, (int)third));
 	break;
 
 	/* IPC_* and SHM_* command values are the same on all linux platforms */
-- 
1.7.1

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

* [Qemu-devel] [PATCH 05/12] linux-user: Conditionally Pass Attribute Pointer to mq_open()
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (3 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 04/12] linux-user: Make ipc syscall's third argument an abi_long Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:10   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 06/12] linux-user: Detect Negative Message Sizes in msgsnd System Call Tom Musta
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

The mq_open system call takes an optional struct mq_attr pointer
argument in the fourth position.  This pointer is used when O_CREAT
is specified in the flags (second) argument.  It may be NULL, in
which case the queue is created with implementation defined attributes.

Change the code to properly handle the case when NULL is passed in the
arg4 position.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bf6dd1e..c0c0434 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9078,12 +9078,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
     case TARGET_NR_mq_open:
         {
-            struct mq_attr posix_mq_attr;
+            struct mq_attr posix_mq_attr, *attrp;
 
             p = lock_user_string(arg1 - 1);
-            if (arg4 != 0)
+            if (arg4 != 0) {
                 copy_from_user_mq_attr (&posix_mq_attr, arg4);
-            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
+                attrp = &posix_mq_attr;
+            } else {
+                attrp = 0;
+            }
+            ret = get_errno(mq_open(p, arg2, arg3, attrp));
             unlock_user (p, arg1, 0);
         }
         break;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 06/12] linux-user: Detect Negative Message Sizes in msgsnd System Call
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (4 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 05/12] linux-user: Conditionally Pass Attribute Pointer to mq_open() Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:26   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 07/12] linux-user: Handle NULL argument to sched_{get, set}param Tom Musta
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

The msgsnd system call takes an argument that describes the message
size (msgsz) and is of type size_t.  The system call should set
errno to EINVAL in the event that a negative message size is passed.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c0c0434..f524a39 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2870,12 +2870,16 @@ struct target_msgbuf {
 };
 
 static inline abi_long do_msgsnd(int msqid, abi_long msgp,
-                                 unsigned int msgsz, int msgflg)
+                                 ssize_t msgsz, int msgflg)
 {
     struct target_msgbuf *target_mb;
     struct msgbuf *host_mb;
     abi_long ret = 0;
 
+    if (msgsz < 0) {
+        return -TARGET_EINVAL;
+    }
+
     if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
         return -TARGET_EFAULT;
     host_mb = malloc(msgsz+sizeof(long));
-- 
1.7.1

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

* [Qemu-devel] [PATCH 07/12] linux-user: Handle NULL argument to sched_{get, set}param
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (5 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 06/12] linux-user: Detect Negative Message Sizes in msgsnd System Call Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:32   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 08/12] linux-user: Detect fault in sched_rr_get_interval Tom Musta
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

The sched_getparam and sched_setparam system calls take a pointer
argument to a sched_param structure.  When this pointer is null,
errno should be set to EINVAL.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f524a39..5f193cd 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7699,6 +7699,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             struct sched_param *target_schp;
             struct sched_param schp;
 
+            if (arg2 == 0) {
+                return -TARGET_EINVAL;
+            }
             if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
                 goto efault;
             schp.sched_priority = tswap32(target_schp->sched_priority);
@@ -7710,6 +7713,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         {
             struct sched_param *target_schp;
             struct sched_param schp;
+
+            if (arg2 == 0) {
+                return -TARGET_EINVAL;
+            }
             ret = get_errno(sched_getparam(arg1, &schp));
             if (!is_error(ret)) {
                 if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
-- 
1.7.1

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

* [Qemu-devel] [PATCH 08/12] linux-user: Detect fault in sched_rr_get_interval
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (6 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 07/12] linux-user: Handle NULL argument to sched_{get, set}param Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:34   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2 Tom Musta
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

Properly detect a fault when attempting to store into an invalid
struct timespec pointer.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5f193cd..95cee0b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7754,7 +7754,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             struct timespec ts;
             ret = get_errno(sched_rr_get_interval(arg1, &ts));
             if (!is_error(ret)) {
-                host_to_target_timespec(arg2, &ts);
+                ret = host_to_target_timespec(arg2, &ts);
             }
         }
         break;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (7 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 08/12] linux-user: Detect fault in sched_rr_get_interval Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:39   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC Tom Musta
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

The ELF V2 ABI for PPC64 defines MINSIGSTKSZ as 4096 bytes whereas it was
2048 previously.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/signal.c b/linux-user/signal.c
index cdfcc52..b2a6e53 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -617,6 +617,15 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
     {
         struct target_sigaltstack *uss;
         struct target_sigaltstack ss;
+        size_t minstacksize = MINSIGSTKSZ;
+
+#if defined(TARGET_PPC64)
+        /* ELF V2 for PPC64 has a 4K minimum stack size for signal handlers */
+        struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
+        if (get_ppc64_abi(image) > 1) {
+            minstacksize = 4096;
+        }
+#endif
 
 	ret = -TARGET_EFAULT;
         if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)) {
@@ -642,8 +651,9 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
             ss.ss_sp = 0;
 	} else {
             ret = -TARGET_ENOMEM;
-            if (ss.ss_size < MINSIGSTKSZ)
+            if (ss.ss_size < minstacksize) {
                 goto out;
+            }
 	}
 
         target_sigaltstack_used.ss_sp = ss.ss_sp;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (8 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2 Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:42   ` Peter Maydell
  2014-08-04 17:43   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 11/12] linux-user: Support target-to-host translation of mlockall argument Tom Musta
                   ` (2 subsequent siblings)
  12 siblings, 2 replies; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

The clock_nanosleep syscall is unusual in that it returns positive
numbers in error handling situations, versus returning -1 and setting
errno, or returning a negative errno value.  On POWER, the kernel will
set the SO bit of CR0 to indicate failure in a syscall.  QEMU has
generic handling to do this for syscalls with standard return values.

Add special case code for clock_nanosleep to handle CR0 properly.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 95cee0b..5660520 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8993,6 +8993,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
         if (arg4)
             host_to_target_timespec(arg4, &ts);
+
+#if defined(TARGET_PPC) || defined(TARGET_PPC64)
+        /* clock_nanosleep is odd in that it returns positive errno values.
+         * On PPC, CR0 bit 3 should be set in such a situation. */
+        if (ret) {
+            ((CPUPPCState *)cpu_env)->crf[0] |= 1;
+        }
+#endif
         break;
     }
 #endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 11/12] linux-user: Support target-to-host translation of mlockall argument
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (9 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:19   ` Peter Maydell
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 12/12] linux-user: writev Partial Writes Tom Musta
  2014-08-12 14:54 ` [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Riku Voipio
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

The argument to the mlockall system call is not necessarily the same on
all platforms and thus may require translation prior to passing to the
host.

For example, PowerPC 64 bit platforms define values for MCL_CURRENT
(0x2000) and MCL_FUTURE (0x4000) which are different from Intel platforms
(0x1 and 0x2, respectively)

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5660520..fea54be 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4934,6 +4934,34 @@ static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
     return 0;
 }
 
+#if defined(TARGET_NR_mlockall)
+
+#if defined(TARGET_PPC64)
+#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
+#define TARGET_MLOCKALL_MCL_FUTURE  0x4000
+#endif
+
+static inline int target_to_host_mlockall_arg(int arg)
+{
+    int result = 0;
+
+#ifdef TARGET_MLOCKALL_MCL_CURRENT
+    if (arg & TARGET_MLOCKALL_MCL_CURRENT) {
+        result |= MCL_CURRENT;
+        arg ^= TARGET_MLOCKALL_MCL_CURRENT;
+    }
+#endif
+#ifdef TARGET_MLOCKALL_MCL_FUTURE
+    if (arg & TARGET_MLOCKALL_MCL_FUTURE) {
+        result |= MCL_FUTURE;
+        arg ^= TARGET_MLOCKALL_MCL_FUTURE;
+    }
+#endif
+    result |= arg;
+    return result;
+}
+#endif
+
 #if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
 static inline abi_long host_to_target_stat64(void *cpu_env,
                                              abi_ulong target_addr,
@@ -6783,7 +6811,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_mlockall
     case TARGET_NR_mlockall:
-        ret = get_errno(mlockall(arg1));
+        ret = get_errno(mlockall(target_to_host_mlockall_arg(arg1)));
         break;
 #endif
 #ifdef TARGET_NR_munlockall
-- 
1.7.1

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

* [Qemu-devel] [PATCH 12/12] linux-user: writev Partial Writes
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (10 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 11/12] linux-user: Support target-to-host translation of mlockall argument Tom Musta
@ 2014-08-04 16:45 ` Tom Musta
  2014-08-04 17:29   ` Peter Maydell
  2014-08-12 14:54 ` [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Riku Voipio
  12 siblings, 1 reply; 30+ messages in thread
From: Tom Musta @ 2014-08-04 16:45 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Tom Musta, riku.voipio, agraf

Although not technically not required by POSIX, the writev system call will
typically write out its buffers individually.  That is, if the first buffer
is written successfully, but the second buffer pointer is invalid, then
the first chuck will be written and its size is returned.

Signed-off-by: Tom Musta <tommusta@gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fea54be..19e78dc 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1798,6 +1798,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
     abi_ulong total_len, max_len;
     int i;
     int err = 0;
+    int bad_address = 0;
 
     if (count == 0) {
         errno = 0;
@@ -1838,9 +1839,20 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
             vec[i].iov_base = 0;
         } else {
             vec[i].iov_base = lock_user(type, base, len, copy);
+            /* If the first buffer pointer is bad, this is a fault.  But
+             * subsequent bad buffers will result in a partial write; this
+             * is realized by filling the vector with null pointers and
+             * zero lengths. */
             if (!vec[i].iov_base) {
-                err = EFAULT;
-                goto fail;
+                if (i == 0) {
+                    err = EFAULT;
+                    goto fail;
+                } else {
+                    bad_address = 1;
+                }
+            }
+            if (bad_address) {
+                len = 0;
             }
             if (len > max_len - total_len) {
                 len = max_len - total_len;
-- 
1.7.1

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

* Re: [Qemu-devel] [PATCH 02/12] linux-user: Dereference Pointer Argument to ipc/semctl Sys Call
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 02/12] linux-user: Dereference Pointer Argument to ipc/semctl Sys Call Tom Musta
@ 2014-08-04 17:04   ` Peter Maydell
  2014-08-04 18:21     ` Tom Musta
  0 siblings, 1 reply; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:04 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> When the ipc system call is used to wrap a semctl system call,
> the ptr argument to ipc needs to be dereferenced prior to passing
> it to the semctl handler.  This is because the fourth argument to
> semctl is a union and not a pointer to a union.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 540001c..229c482 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -3135,9 +3135,15 @@ static abi_long do_ipc(unsigned int call, int first,
>          ret = get_errno(semget(first, second, third));
>          break;
>
> -    case IPCOP_semctl:
> -        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
> +    case IPCOP_semctl: {
> +        /* The semun argument to semctl is passed by value, so dereference the
> +         * ptr argument. */
> +        abi_ulong atptr;
> +        get_user_ual(atptr, (abi_ulong)ptr);
> +        ret = do_semctl(first, second, third,
> +                (union target_semun)(abi_ulong) atptr);

My review comments on this patch from Paul Burton:
http://patchwork.ozlabs.org/patch/363201/
apply here too: the change here to use get_user_ual()
looks plausible, except that do_semctl() writes to the
target_su in some cases, so how is this supposed to
pass the value back to the caller? Probably do_semctl()
is buggy, but the whole thing needs to be scrutinized
and fixed, not just this little corner...

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 04/12] linux-user: Make ipc syscall's third argument an abi_long
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 04/12] linux-user: Make ipc syscall's third argument an abi_long Tom Musta
@ 2014-08-04 17:09   ` Peter Maydell
  0 siblings, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:09 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> For those target ABIs that use the ipc system call (e.g. POWER),
> the third argument is used in the shmat path as a pointer.  It
> therefore must be declared as an abi_long (versus int) so that
> the address bits are not lost in truncation.  The "int-ness" of
> this argument is retained for all other system calls via an
> explicit cast.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index fb03e96..bf6dd1e 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -3122,7 +3122,7 @@ static inline abi_long do_shmdt(abi_ulong shmaddr)
>  /* ??? This only works with linear mappings.  */
>  /* do_ipc() must return target values and target errnos. */
>  static abi_long do_ipc(unsigned int call, int first,
> -                       int second, int third,
> +                       int second, abi_long third,
>                         abi_long ptr, abi_long fifth)

Given where and how this is called, I would suggest
that all its arguments (except 'call') hould be abi_long,
because it's just out-of-line handling of one particular case
from do_syscall(), and the arguments there are all abi_long.

>  {
>      int version;
> @@ -3137,7 +3137,7 @@ static abi_long do_ipc(unsigned int call, int first,
>          break;
>
>      case IPCOP_semget:
> -        ret = get_errno(semget(first, second, third));
> +        ret = get_errno(semget(first, second, (int)third));
>          break;

This cast isn't needed because semget()'s third argument is
int type anyway. I suspect most or perhaps even all the other
casts below are also unneeded.

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 05/12] linux-user: Conditionally Pass Attribute Pointer to mq_open()
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 05/12] linux-user: Conditionally Pass Attribute Pointer to mq_open() Tom Musta
@ 2014-08-04 17:10   ` Peter Maydell
  0 siblings, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:10 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> The mq_open system call takes an optional struct mq_attr pointer
> argument in the fourth position.  This pointer is used when O_CREAT
> is specified in the flags (second) argument.  It may be NULL, in
> which case the queue is created with implementation defined attributes.
>
> Change the code to properly handle the case when NULL is passed in the
> arg4 position.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 11/12] linux-user: Support target-to-host translation of mlockall argument
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 11/12] linux-user: Support target-to-host translation of mlockall argument Tom Musta
@ 2014-08-04 17:19   ` Peter Maydell
  0 siblings, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:19 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> The argument to the mlockall system call is not necessarily the same on
> all platforms and thus may require translation prior to passing to the
> host.
>
> For example, PowerPC 64 bit platforms define values for MCL_CURRENT
> (0x2000) and MCL_FUTURE (0x4000) which are different from Intel platforms
> (0x1 and 0x2, respectively)
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 5660520..fea54be 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -4934,6 +4934,34 @@ static inline abi_long host_to_target_itimerspec(abi_ulong target_addr,
>      return 0;
>  }
>
> +#if defined(TARGET_NR_mlockall)
> +
> +#if defined(TARGET_PPC64)
> +#define TARGET_MLOCKALL_MCL_CURRENT 0x2000
> +#define TARGET_MLOCKALL_MCL_FUTURE  0x4000
> +#endif

These shouldn't be here -- they ought to go in some header file
in linux-user/ppc.

> +static inline int target_to_host_mlockall_arg(int arg)
> +{
> +    int result = 0;
> +
> +#ifdef TARGET_MLOCKALL_MCL_CURRENT
> +    if (arg & TARGET_MLOCKALL_MCL_CURRENT) {
> +        result |= MCL_CURRENT;
> +        arg ^= TARGET_MLOCKALL_MCL_CURRENT;
> +    }
> +#endif
> +#ifdef TARGET_MLOCKALL_MCL_FUTURE
> +    if (arg & TARGET_MLOCKALL_MCL_FUTURE) {
> +        result |= MCL_FUTURE;
> +        arg ^= TARGET_MLOCKALL_MCL_FUTURE;
> +    }
> +#endif

Rather than conditionalizing all this on whether
TARGET_MLOCKALL_* are defined we should just
define them for all our target architectures. (Otherwise
other-arch-on-PPC-host won't work.)

The right values are:
MCL_CURRENT:
 * PPC, SPARC, Alpha: 0x2000
 * everything else: 1
MCL_FUTURE:
 * PPC, SPARC, Alpha: 0x4000
 * everything else: 2

It's probably bogus to pass unknown flags through...

(For once MIPS isn't the weirdo.)

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 03/12] linux-user: Properly Handle semun Structure In Cross-Endian Situations
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 03/12] linux-user: Properly Handle semun Structure In Cross-Endian Situations Tom Musta
@ 2014-08-04 17:23   ` Peter Maydell
  0 siblings, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:23 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> The semun union used in the semctl system call contains both an int (val) and
> pointers.  In cross-endian situations on 64 bit targets, the target memory
> must be byte swapped, otherwise the wrong 32 bits are used for the val
> field.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 229c482..fb03e96 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -2647,9 +2647,14 @@ static inline abi_long do_semctl(int semid, int semnum, int cmd,
>      switch( cmd ) {
>         case GETVAL:
>         case SETVAL:
> +#if TARGET_ABI_BITS == 64
> +            /* In 64 bit cross endian situations, we will erroneously pick up
> +             * the wrong half of the union for the "val" element.  To rectify
> +             * this, the entire structure is byteswaped. */

"byteswapped".

> +            target_su.buf = tswapal(target_su.buf);
> +#endif

This feels weird; surely there's a way of phrasing this
that doesn't require an #ifdef on TARGET_ABI_BITS?

>              arg.val = tswap32(target_su.val);
>              ret = get_errno(semctl(semid, semnum, cmd, arg));
> -            target_su.val = tswap32(arg.val);

This deleted line isn't mentioned in the commit message...

>              break;
>         case GETALL:
>         case SETALL:

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 06/12] linux-user: Detect Negative Message Sizes in msgsnd System Call
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 06/12] linux-user: Detect Negative Message Sizes in msgsnd System Call Tom Musta
@ 2014-08-04 17:26   ` Peter Maydell
  0 siblings, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:26 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> The msgsnd system call takes an argument that describes the message
> size (msgsz) and is of type size_t.  The system call should set
> errno to EINVAL in the event that a negative message size is passed.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index c0c0434..f524a39 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -2870,12 +2870,16 @@ struct target_msgbuf {
>  };
>
>  static inline abi_long do_msgsnd(int msqid, abi_long msgp,
> -                                 unsigned int msgsz, int msgflg)
> +                                 ssize_t msgsz, int msgflg)
>  {
>      struct target_msgbuf *target_mb;
>      struct msgbuf *host_mb;
>      abi_long ret = 0;
>
> +    if (msgsz < 0) {
> +        return -TARGET_EINVAL;
> +    }
> +
>      if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
>          return -TARGET_EFAULT;
>      host_mb = malloc(msgsz+sizeof(long));
> --

This won't catch the case where the guest's abi_long is
64 bit but the host's ssize_t is only 32 bits and the guest
passed us a negative value with bit 31 zero, but we
probably don't really care about that.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 12/12] linux-user: writev Partial Writes
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 12/12] linux-user: writev Partial Writes Tom Musta
@ 2014-08-04 17:29   ` Peter Maydell
  0 siblings, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:29 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> Although not technically not required by POSIX, the writev system call will
> typically write out its buffers individually.  That is, if the first buffer
> is written successfully, but the second buffer pointer is invalid, then
> the first chuck will be written and its size is returned.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index fea54be..19e78dc 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -1798,6 +1798,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
>      abi_ulong total_len, max_len;
>      int i;
>      int err = 0;
> +    int bad_address = 0;

I would use a bool here rather than int. Other than that nit,


Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 07/12] linux-user: Handle NULL argument to sched_{get, set}param
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 07/12] linux-user: Handle NULL argument to sched_{get, set}param Tom Musta
@ 2014-08-04 17:32   ` Peter Maydell
  0 siblings, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:32 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> The sched_getparam and sched_setparam system calls take a pointer
> argument to a sched_param structure.  When this pointer is null,
> errno should be set to EINVAL.

Don't we also need this for the other syscall which takes a
sched_param pointer, sched_setscheduler?

(Strictly speaking I think we could get away without the check
in sched_getparam, because the host syscall will return EINVAL
for us, but I'm happy for us to put the explicit check in for
consistency.)

>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index f524a39..5f193cd 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -7699,6 +7699,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>              struct sched_param *target_schp;
>              struct sched_param schp;
>
> +            if (arg2 == 0) {
> +                return -TARGET_EINVAL;
> +            }
>              if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
>                  goto efault;
>              schp.sched_priority = tswap32(target_schp->sched_priority);
> @@ -7710,6 +7713,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          {
>              struct sched_param *target_schp;
>              struct sched_param schp;
> +
> +            if (arg2 == 0) {
> +                return -TARGET_EINVAL;
> +            }
>              ret = get_errno(sched_getparam(arg1, &schp))
>              if (!is_error(ret)) {
>                  if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
> --
> 1.7.1

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 08/12] linux-user: Detect fault in sched_rr_get_interval
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 08/12] linux-user: Detect fault in sched_rr_get_interval Tom Musta
@ 2014-08-04 17:34   ` Peter Maydell
  0 siblings, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:34 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> Properly detect a fault when attempting to store into an invalid
> struct timespec pointer.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 5f193cd..95cee0b 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -7754,7 +7754,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>              struct timespec ts;
>              ret = get_errno(sched_rr_get_interval(arg1, &ts));
>              if (!is_error(ret)) {
> -                host_to_target_timespec(arg2, &ts);
> +                ret = host_to_target_timespec(arg2, &ts);
>              }
>          }
>          break;

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

A quick grep suggests there may well be other callsites that
should be checking the host_to_target_timespec() return
value as well...

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2 Tom Musta
@ 2014-08-04 17:39   ` Peter Maydell
  2014-08-12 15:57     ` Alexander Graf
  0 siblings, 1 reply; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:39 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> The ELF V2 ABI for PPC64 defines MINSIGSTKSZ as 4096 bytes whereas it was
> 2048 previously.

Alpha and SPARC also have a 4096 byte MINSIGSTKSZ...

> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index cdfcc52..b2a6e53 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -617,6 +617,15 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
>      {
>          struct target_sigaltstack *uss;
>          struct target_sigaltstack ss;
> +        size_t minstacksize = MINSIGSTKSZ;
> +
> +#if defined(TARGET_PPC64)
> +        /* ELF V2 for PPC64 has a 4K minimum stack size for signal handlers */
> +        struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
> +        if (get_ppc64_abi(image) > 1) {
> +            minstacksize = 4096;
> +        }
> +#endif

Shouldn't we just define and use a TARGET_MINSIGSTKSZ ?
Checking against the host's MINSIGSTKSZ is wrong, I think.

Again, define the TARGET_MINSIGSTKSZ in a file in
linux-user/$ARCH/, for all targets:
 alpha, sparc, ppc64: 4096
 everything else: 2048
(itanium is weird here but we don't support that for linux-user guests)

>         ret = -TARGET_EFAULT;
>          if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)) {
> @@ -642,8 +651,9 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
>              ss.ss_sp = 0;
>         } else {
>              ret = -TARGET_ENOMEM;
> -            if (ss.ss_size < MINSIGSTKSZ)
> +            if (ss.ss_size < minstacksize) {
>                  goto out;
> +            }
>         }
>
>          target_sigaltstack_used.ss_sp = ss.ss_sp;
> --
> 1.7.1

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC Tom Musta
@ 2014-08-04 17:42   ` Peter Maydell
  2014-08-04 17:43   ` Peter Maydell
  1 sibling, 0 replies; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:42 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> The clock_nanosleep syscall is unusual in that it returns positive
> numbers in error handling situations, versus returning -1 and setting
> errno, or returning a negative errno value.  On POWER, the kernel will
> set the SO bit of CR0 to indicate failure in a syscall.  QEMU has
> generic handling to do this for syscalls with standard return values.
>
> Add special case code for clock_nanosleep to handle CR0 properly.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 95cee0b..5660520 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8993,6 +8993,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
>          if (arg4)
>              host_to_target_timespec(arg4, &ts);
> +
> +#if defined(TARGET_PPC) || defined(TARGET_PPC64)
> +        /* clock_nanosleep is odd in that it returns positive errno values.
> +         * On PPC, CR0 bit 3 should be set in such a situation. */
> +        if (ret) {
> +            ((CPUPPCState *)cpu_env)->crf[0] |= 1;
> +        }
> +#endif
>          break;
>      }
>  #endif

New target-specific ifdefs in syscall.c make me sad, but the
alternative would be to upend the do_syscall() calling
convention to pass return value and success/failure separately
or something, which is clearly ludicrous for this corner case. So

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC Tom Musta
  2014-08-04 17:42   ` Peter Maydell
@ 2014-08-04 17:43   ` Peter Maydell
  2014-08-04 18:17     ` Tom Musta
  1 sibling, 1 reply; 30+ messages in thread
From: Peter Maydell @ 2014-08-04 17:43 UTC (permalink / raw)
  To: Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
> The clock_nanosleep syscall is unusual in that it returns positive
> numbers in error handling situations, versus returning -1 and setting
> errno, or returning a negative errno value.  On POWER, the kernel will
> set the SO bit of CR0 to indicate failure in a syscall.  QEMU has
> generic handling to do this for syscalls with standard return values.
>
> Add special case code for clock_nanosleep to handle CR0 properly.
>
> Signed-off-by: Tom Musta <tommusta@gmail.com>
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 95cee0b..5660520 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8993,6 +8993,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
>          if (arg4)
>              host_to_target_timespec(arg4, &ts);
> +
> +#if defined(TARGET_PPC) || defined(TARGET_PPC64)

...isn't TARGET_PPC always defined if TARGET_PPC64 is?
(ie second condition in the || is unnecessary)

-- PMM

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

* Re: [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC
  2014-08-04 17:43   ` Peter Maydell
@ 2014-08-04 18:17     ` Tom Musta
  0 siblings, 0 replies; 30+ messages in thread
From: Tom Musta @ 2014-08-04 18:17 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 8/4/2014 12:43 PM, Peter Maydell wrote:
> On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
>> The clock_nanosleep syscall is unusual in that it returns positive
>> numbers in error handling situations, versus returning -1 and setting
>> errno, or returning a negative errno value.  On POWER, the kernel will
>> set the SO bit of CR0 to indicate failure in a syscall.  QEMU has
>> generic handling to do this for syscalls with standard return values.
>>
>> Add special case code for clock_nanosleep to handle CR0 properly.
>>
>> Signed-off-by: Tom Musta <tommusta@gmail.com>
>>
>> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
>> index 95cee0b..5660520 100644
>> --- a/linux-user/syscall.c
>> +++ b/linux-user/syscall.c
>> @@ -8993,6 +8993,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>>          ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
>>          if (arg4)
>>              host_to_target_timespec(arg4, &ts);
>> +
>> +#if defined(TARGET_PPC) || defined(TARGET_PPC64)
> 
> ...isn't TARGET_PPC always defined if TARGET_PPC64 is?
> (ie second condition in the || is unnecessary)
> 
> -- PMM
> 

You are correct.  I was thinking "TARGET_PPC" was a euphemism for 32 bit Power
(since --target=ppc-softmmy,ppc-linux-user are used to configure 32 bit
implementations).  But I see now in config-target.h that this is not the case.

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

* Re: [Qemu-devel] [PATCH 02/12] linux-user: Dereference Pointer Argument to ipc/semctl Sys Call
  2014-08-04 17:04   ` Peter Maydell
@ 2014-08-04 18:21     ` Tom Musta
  0 siblings, 0 replies; 30+ messages in thread
From: Tom Musta @ 2014-08-04 18:21 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Riku Voipio, qemu-ppc, QEMU Developers, Alexander Graf

On 8/4/2014 12:04 PM, Peter Maydell wrote:
> On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
>> When the ipc system call is used to wrap a semctl system call,
>> the ptr argument to ipc needs to be dereferenced prior to passing
>> it to the semctl handler.  This is because the fourth argument to
>> semctl is a union and not a pointer to a union.
>>
>> Signed-off-by: Tom Musta <tommusta@gmail.com>
>>
>> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
>> index 540001c..229c482 100644
>> --- a/linux-user/syscall.c
>> +++ b/linux-user/syscall.c
>> @@ -3135,9 +3135,15 @@ static abi_long do_ipc(unsigned int call, int first,
>>          ret = get_errno(semget(first, second, third));
>>          break;
>>
>> -    case IPCOP_semctl:
>> -        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
>> +    case IPCOP_semctl: {
>> +        /* The semun argument to semctl is passed by value, so dereference the
>> +         * ptr argument. */
>> +        abi_ulong atptr;
>> +        get_user_ual(atptr, (abi_ulong)ptr);
>> +        ret = do_semctl(first, second, third,
>> +                (union target_semun)(abi_ulong) atptr);
> 
> My review comments on this patch from Paul Burton:
> http://patchwork.ozlabs.org/patch/363201/
> apply here too: the change here to use get_user_ual()
> looks plausible, except that do_semctl() writes to the
> target_su in some cases, so how is this supposed to
> pass the value back to the caller? Probably do_semctl()
> is buggy, but the whole thing needs to be scrutinized
> and fixed, not just this little corner...
> 
> thanks
> -- PMM
> 

Thanks for your review of these patches, Peter.

It appears that Paul never resolved your concerns and resubmitted his patch (?).
To be honest, I'm not sure yet that I yet see what has you concerned, but I
will attempt an end-to-end review of the semctl path. (QEMU, glibc, kernel)

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

* Re: [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power
  2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
                   ` (11 preceding siblings ...)
  2014-08-04 16:45 ` [Qemu-devel] [PATCH 12/12] linux-user: writev Partial Writes Tom Musta
@ 2014-08-12 14:54 ` Riku Voipio
  2014-08-12 15:23   ` Tom Musta
  12 siblings, 1 reply; 30+ messages in thread
From: Riku Voipio @ 2014-08-12 14:54 UTC (permalink / raw)
  To: Tom Musta; +Cc: riku.voipio, qemu-ppc, qemu-devel, agraf

Hi,

On Mon, Aug 04, 2014 at 11:45:27AM -0500, Tom Musta wrote:
> This series of patches is the result of executing the Linux Test Program
> (LTP) System Call bucket (https://github.com/linux-test-project/ltp)
> on the 64 bit big and little endian linux user mode targets for Power.
> 
> Some of the changes are not technically unique to Power, but are effectively
> so.  For example, Power may be the only runtime that uses the ipc system call
> as a hub for other system calls (semctl, semop, ...).

Thanks for the series - Peter had some comments on a dew of them - would
you have time to address them and send a v2 series soonish? Then I can
include them in my next pull request already.

Riku

> The series is dependent on my previous patch series that adds signal handler
> support on PPC64 (http://lists.nongnu.org/archive/html/qemu-ppc/2014-06/msg00802.html).
> That series has gone into Alex's ppcnext branch for QEMU 2.2.
> 
> Tom Musta (12):
>   linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2
>   linux-user: Dereference Pointer Argument to ipc/semctl Sys Call
>   linux-user: Properly Handle semun Structure In Cross-Endian
>     Situations
>   linux-user: Make ipc syscall's third argument an abi_long
>   linux-user: Conditionally Pass Attribute Pointer to mq_open()
>   linux-user: Detect Negative Message Sizes in msgsnd System Call
>   linux-user: Handle NULL argument to sched_{get,set}param
>   linux-user: Detect fault in sched_rr_get_interval
>   linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2
>   linux-user: clock_nanosleep errno Handling on PPC
>   linux-user: Support target-to-host translation of mlockall argument
>   linux-user: writev Partial Writes
> 
>  linux-user/signal.c  |   12 +++++-
>  linux-user/syscall.c |  113 ++++++++++++++++++++++++++++++++++++++++++--------
>  2 files changed, 107 insertions(+), 18 deletions(-)
> 

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

* Re: [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power
  2014-08-12 14:54 ` [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Riku Voipio
@ 2014-08-12 15:23   ` Tom Musta
  0 siblings, 0 replies; 30+ messages in thread
From: Tom Musta @ 2014-08-12 15:23 UTC (permalink / raw)
  To: Riku Voipio; +Cc: riku.voipio, qemu-ppc, qemu-devel, agraf

On 8/12/2014 9:54 AM, Riku Voipio wrote:
> Hi,
> 
> On Mon, Aug 04, 2014 at 11:45:27AM -0500, Tom Musta wrote:
>> This series of patches is the result of executing the Linux Test Program
>> (LTP) System Call bucket (https://github.com/linux-test-project/ltp)
>> on the 64 bit big and little endian linux user mode targets for Power.
>>
>> Some of the changes are not technically unique to Power, but are effectively
>> so.  For example, Power may be the only runtime that uses the ipc system call
>> as a hub for other system calls (semctl, semop, ...).
> 
> Thanks for the series - Peter had some comments on a dew of them - would
> you have time to address them and send a v2 series soonish? Then I can
> include them in my next pull request already.
> 
> Riku
> 

Riku:  yes ... I hope to get V2 out yet today.

>> The series is dependent on my previous patch series that adds signal handler
>> support on PPC64 (http://lists.nongnu.org/archive/html/qemu-ppc/2014-06/msg00802.html).
>> That series has gone into Alex's ppcnext branch for QEMU 2.2.
>>
>> Tom Musta (12):
>>   linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2
>>   linux-user: Dereference Pointer Argument to ipc/semctl Sys Call
>>   linux-user: Properly Handle semun Structure In Cross-Endian
>>     Situations
>>   linux-user: Make ipc syscall's third argument an abi_long
>>   linux-user: Conditionally Pass Attribute Pointer to mq_open()
>>   linux-user: Detect Negative Message Sizes in msgsnd System Call
>>   linux-user: Handle NULL argument to sched_{get,set}param
>>   linux-user: Detect fault in sched_rr_get_interval
>>   linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2
>>   linux-user: clock_nanosleep errno Handling on PPC
>>   linux-user: Support target-to-host translation of mlockall argument
>>   linux-user: writev Partial Writes
>>
>>  linux-user/signal.c  |   12 +++++-
>>  linux-user/syscall.c |  113 ++++++++++++++++++++++++++++++++++++++++++--------
>>  2 files changed, 107 insertions(+), 18 deletions(-)
>>

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

* Re: [Qemu-devel] [PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2
  2014-08-04 17:39   ` Peter Maydell
@ 2014-08-12 15:57     ` Alexander Graf
  0 siblings, 0 replies; 30+ messages in thread
From: Alexander Graf @ 2014-08-12 15:57 UTC (permalink / raw)
  To: Peter Maydell, Tom Musta; +Cc: Riku Voipio, qemu-ppc, QEMU Developers


On 04.08.14 19:39, Peter Maydell wrote:
> On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote:
>> The ELF V2 ABI for PPC64 defines MINSIGSTKSZ as 4096 bytes whereas it was
>> 2048 previously.
> Alpha and SPARC also have a 4096 byte MINSIGSTKSZ...
>
>> Signed-off-by: Tom Musta <tommusta@gmail.com>
>>
>> diff --git a/linux-user/signal.c b/linux-user/signal.c
>> index cdfcc52..b2a6e53 100644
>> --- a/linux-user/signal.c
>> +++ b/linux-user/signal.c
>> @@ -617,6 +617,15 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
>>       {
>>           struct target_sigaltstack *uss;
>>           struct target_sigaltstack ss;
>> +        size_t minstacksize = MINSIGSTKSZ;
>> +
>> +#if defined(TARGET_PPC64)
>> +        /* ELF V2 for PPC64 has a 4K minimum stack size for signal handlers */
>> +        struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
>> +        if (get_ppc64_abi(image) > 1) {
>> +            minstacksize = 4096;
>> +        }
>> +#endif
> Shouldn't we just define and use a TARGET_MINSIGSTKSZ ?
> Checking against the host's MINSIGSTKSZ is wrong, I think.
>
> Again, define the TARGET_MINSIGSTKSZ in a file in
> linux-user/$ARCH/, for all targets:
>   alpha, sparc, ppc64: 4096
>   everything else: 2048
> (itanium is weird here but we don't support that for linux-user guests)

and supporting ia64 is really hard, because it uses the full 64bit 
virtual address space which we can't provide on x86_64.


Alex

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

end of thread, other threads:[~2014-08-12 15:57 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-04 16:45 [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Tom Musta
2014-08-04 16:45 ` [Qemu-devel] [PATCH 01/12] linux-user: PPC64 semid_ds Doesnt Include _unused1 and _unused2 Tom Musta
2014-08-04 16:45 ` [Qemu-devel] [PATCH 02/12] linux-user: Dereference Pointer Argument to ipc/semctl Sys Call Tom Musta
2014-08-04 17:04   ` Peter Maydell
2014-08-04 18:21     ` Tom Musta
2014-08-04 16:45 ` [Qemu-devel] [PATCH 03/12] linux-user: Properly Handle semun Structure In Cross-Endian Situations Tom Musta
2014-08-04 17:23   ` Peter Maydell
2014-08-04 16:45 ` [Qemu-devel] [PATCH 04/12] linux-user: Make ipc syscall's third argument an abi_long Tom Musta
2014-08-04 17:09   ` Peter Maydell
2014-08-04 16:45 ` [Qemu-devel] [PATCH 05/12] linux-user: Conditionally Pass Attribute Pointer to mq_open() Tom Musta
2014-08-04 17:10   ` Peter Maydell
2014-08-04 16:45 ` [Qemu-devel] [PATCH 06/12] linux-user: Detect Negative Message Sizes in msgsnd System Call Tom Musta
2014-08-04 17:26   ` Peter Maydell
2014-08-04 16:45 ` [Qemu-devel] [PATCH 07/12] linux-user: Handle NULL argument to sched_{get, set}param Tom Musta
2014-08-04 17:32   ` Peter Maydell
2014-08-04 16:45 ` [Qemu-devel] [PATCH 08/12] linux-user: Detect fault in sched_rr_get_interval Tom Musta
2014-08-04 17:34   ` Peter Maydell
2014-08-04 16:45 ` [Qemu-devel] [PATCH 09/12] linux-user: Minimum Sig Handler Stack Size for PPC64 ELF V2 Tom Musta
2014-08-04 17:39   ` Peter Maydell
2014-08-12 15:57     ` Alexander Graf
2014-08-04 16:45 ` [Qemu-devel] [PATCH 10/12] linux-user: clock_nanosleep errno Handling on PPC Tom Musta
2014-08-04 17:42   ` Peter Maydell
2014-08-04 17:43   ` Peter Maydell
2014-08-04 18:17     ` Tom Musta
2014-08-04 16:45 ` [Qemu-devel] [PATCH 11/12] linux-user: Support target-to-host translation of mlockall argument Tom Musta
2014-08-04 17:19   ` Peter Maydell
2014-08-04 16:45 ` [Qemu-devel] [PATCH 12/12] linux-user: writev Partial Writes Tom Musta
2014-08-04 17:29   ` Peter Maydell
2014-08-12 14:54 ` [Qemu-devel] [PATCH 00/12] target-ppc: Linux-User Mode Bug Fixes for Power Riku Voipio
2014-08-12 15:23   ` Tom Musta

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.