All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues
@ 2016-09-14 20:19 Aleksandar Markovic
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall Aleksandar Markovic
                   ` (7 more replies)
  0 siblings, 8 replies; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:19 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

v4->v5:

    - removed three cleanup patches

v3->v4:

    - rebased to the latest code
    - added patch on clock_adjtime() support
    - minor commit messages improvements

v2->v3:

    - rebased to the latest code
    - merged patches on adjtimex(), sysfs(), and ustat() from another series
    - added patch on socketcall() support
    - cleanup patches reorganized

v1->v2:

    - improved usage of "#ifdefs" in patch on syslog()
    - removed EIDRM-related code from patch on msgrcv(), since this error
      code is already handled well
    - added three cleanup patches

(also, v1 for some reason did not appear on qemu-devel, but mails are sent)

This series fixes certain Qemu user mode issues. The fixes mainly originate
from observation of LTP tests failures for execution in Qemu user mode on
various platforms. The series also contains a cleanup patch.

Aleksandar Markovic (8):
  linux-user: Add support for adjtimex() syscall
  linux-user: Add support for clock_adjtime() syscall
  linux-user: Add support for sysfs() syscall
  linux-user: Add support for ustat() syscall
  linux-user: Fix msgrcv() and msgsnd() syscalls support
  linux-user: Fix socketcall() syscall support
  linux-user: Fix syslog() syscall support
  linux-user: Remove a duplicate item from strace.list

 linux-user/strace.c       | 118 +++++++++++++++++++++++++
 linux-user/strace.list    |  12 +--
 linux-user/syscall.c      | 221 ++++++++++++++++++++++++++++++++++++++++++----
 linux-user/syscall_defs.h |  53 +++++++++++
 4 files changed, 380 insertions(+), 24 deletions(-)

-- 
2.9.3

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

* [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
  2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
@ 2016-09-14 20:19 ` Aleksandar Markovic
  2016-09-17 18:40   ` Laurent Vivier
  2016-09-22  4:42   ` Riku Voipio
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 2/8] linux-user: Add support for clock_adjtime() syscall Aleksandar Markovic
                   ` (6 subsequent siblings)
  7 siblings, 2 replies; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:19 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

This patch implements Qemu user mode adjtimex() syscall support.

Syscall adjtimex() reads and optionally sets parameters for a clock
adjustment algorithm used in network synchonization or similar scenarios.

The implementation is based on invocation of host's adjtimex(), and
its key part is in the correspondent case segment of the main switch
statement of the function do_syscall(), in file linux-user/syscalls.c.
Also, support for related structure "timex" is added to the file
linux-user/syscall_defs.h, based on its definition in Linux kernel. All
necessary conversions of the data structures from target to host and from
host to target are covered. Two new functions, target_to_host_timex() and
host_to_target_timex(), are provided for the purpose of such conversions.
Moreover, the relevant support for "-strace" Qemu option is included in
files linux-user/strace.c and linux-user/strace.list.

This patch also fixes failures of LTP tests adjtimex01 and adjtimex02, if
executed in Qemu user mode.

Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/strace.c       | 12 +++++++
 linux-user/strace.list    |  2 +-
 linux-user/syscall.c      | 90 ++++++++++++++++++++++++++++++++++++++++++++++-
 linux-user/syscall_defs.h | 28 +++++++++++++++
 4 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index cc10dc4..7ddcaf8 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -919,6 +919,18 @@ print_access(const struct syscallname *name,
 }
 #endif
 
+#ifdef TARGET_NR_adjtimex
+static void
+print_adjtimex(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+    print_pointer(arg0, 1);
+    print_syscall_epilogue(name);
+}
+#endif
+
 #ifdef TARGET_NR_brk
 static void
 print_brk(const struct syscallname *name,
diff --git a/linux-user/strace.list b/linux-user/strace.list
index aa967a2..9a665a8 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -16,7 +16,7 @@
 { TARGET_NR_add_key, "add_key" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_adjtimex
-{ TARGET_NR_adjtimex, "adjtimex" , NULL, NULL, NULL },
+{ TARGET_NR_adjtimex, "adjtimex" , NULL, print_adjtimex, NULL },
 #endif
 #ifdef TARGET_NR_afs_syscall
 { TARGET_NR_afs_syscall, "afs_syscall" , NULL, NULL, NULL },
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ca06943..5643840 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -35,6 +35,7 @@
 #include <sys/swap.h>
 #include <linux/capability.h>
 #include <sched.h>
+#include <sys/timex.h>
 #ifdef __ia64__
 int __clone2(int (*fn)(void *), void *child_stack_base,
              size_t stack_size, int flags, void *arg, ...);
@@ -6578,6 +6579,78 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
 }
 #endif
 
+#ifdef TARGET_NR_adjtimex
+static inline abi_long target_to_host_timex(struct timex *host_buf,
+                                            abi_long target_addr)
+{
+    struct target_timex *target_buf;
+
+    if (!lock_user_struct(VERIFY_READ, target_buf, target_addr, 1)) {
+        return -TARGET_EFAULT;
+    }
+
+    host_buf->modes = tswap32(target_buf->modes);
+    host_buf->offset = tswapal(target_buf->offset);
+    host_buf->freq = tswapal(target_buf->freq);
+    host_buf->maxerror = tswapal(target_buf->maxerror);
+    host_buf->esterror = tswapal(target_buf->esterror);
+    host_buf->status = tswap32(target_buf->status);
+    host_buf->constant = tswapal(target_buf->constant);
+    host_buf->precision = tswapal(target_buf->precision);
+    host_buf->tolerance = tswapal(target_buf->tolerance);
+    host_buf->time.tv_sec = tswapal(target_buf->time.tv_sec);
+    host_buf->time.tv_usec = tswapal(target_buf->time.tv_usec);
+    host_buf->tick = tswapal(target_buf->tick);
+    host_buf->ppsfreq = tswapal(target_buf->ppsfreq);
+    host_buf->jitter = tswapal(target_buf->jitter);
+    host_buf->shift = tswap32(target_buf->shift);
+    host_buf->stabil = tswapal(target_buf->stabil);
+    host_buf->jitcnt = tswapal(target_buf->jitcnt);
+    host_buf->calcnt = tswapal(target_buf->calcnt);
+    host_buf->errcnt = tswapal(target_buf->errcnt);
+    host_buf->stbcnt = tswapal(target_buf->stbcnt);
+    host_buf->tai = tswap32(target_buf->tai);
+
+    unlock_user_struct(target_buf, target_addr, 0);
+    return 0;
+}
+
+static inline abi_long host_to_target_timex(abi_long target_addr,
+                                            struct timex *host_buf)
+{
+    struct target_timex *target_buf;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_buf, target_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+
+    target_buf->modes = tswap32(host_buf->modes);
+    target_buf->offset = tswapal(host_buf->offset);
+    target_buf->freq = tswapal(host_buf->freq);
+    target_buf->maxerror = tswapal(host_buf->maxerror);
+    target_buf->esterror = tswapal(host_buf->esterror);
+    target_buf->status = tswap32(host_buf->status);
+    target_buf->constant = tswapal(host_buf->constant);
+    target_buf->precision = tswapal(host_buf->precision);
+    target_buf->tolerance = tswapal(host_buf->tolerance);
+    target_buf->time.tv_sec = tswapal(host_buf->time.tv_sec);
+    target_buf->time.tv_usec = tswapal(host_buf->time.tv_usec);
+    target_buf->tick = tswapal(host_buf->tick);
+    target_buf->ppsfreq = tswapal(host_buf->ppsfreq);
+    target_buf->jitter = tswapal(host_buf->jitter);
+    target_buf->shift = tswap32(host_buf->shift);
+    target_buf->stabil = tswapal(host_buf->stabil);
+    target_buf->jitcnt = tswapal(host_buf->jitcnt);
+    target_buf->calcnt = tswapal(host_buf->calcnt);
+    target_buf->errcnt = tswapal(host_buf->errcnt);
+    target_buf->stbcnt = tswapal(host_buf->stbcnt);
+    target_buf->tai = tswap32(host_buf->tai);
+
+    unlock_user_struct(target_buf, target_addr, 1);
+    return 0;
+}
+#endif
+
 static inline abi_long target_to_host_timespec(struct timespec *host_ts,
                                                abi_ulong target_addr)
 {
@@ -9419,8 +9492,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #endif
 #endif
+#ifdef TARGET_NR_adjtimex
     case TARGET_NR_adjtimex:
-        goto unimplemented;
+        {
+            struct timex host_buf;
+
+            if (target_to_host_timex(&host_buf, arg1) != 0) {
+                goto efault;
+            }
+            ret = get_errno(adjtimex(&host_buf));
+            if (!is_error(ret) && arg1) {
+                if (host_to_target_timex(arg1, &host_buf) != 0) {
+                    goto efault;
+                }
+            }
+        }
+        break;
+#endif
 #ifdef TARGET_NR_create_module
     case TARGET_NR_create_module:
 #endif
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 7835654..afd9191 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -207,6 +207,34 @@ struct target_itimerspec {
     struct target_timespec it_value;
 };
 
+struct target_timex {
+    unsigned int modes;          /* Mode selector */
+    abi_long offset;             /* Time offset */
+    abi_long freq;               /* Frequency offset */
+    abi_long maxerror;           /* Maximum error (microseconds) */
+    abi_long esterror;           /* Estimated error (microseconds) */
+    int status;                  /* Clock command/status */
+    abi_long constant;           /* PLL (phase-locked loop) time constant */
+    abi_long precision;          /* Clock precision (microseconds, ro) */
+    abi_long tolerance;          /* Clock freq. tolerance (ppm, ro) */
+    struct target_timeval time;  /* Current time */
+    abi_long tick;               /* Microseconds between clock ticks */
+    abi_long ppsfreq;            /* PPS (pulse per second) frequency */
+    abi_long jitter;             /* PPS jitter (ro); nanoseconds */
+    int shift;                   /* PPS interval duration (seconds) */
+    abi_long stabil;             /* PPS stability */
+    abi_long jitcnt;             /* PPS jitter limit exceeded (ro) */
+    abi_long calcnt;             /* PPS calibration intervals */
+    abi_long errcnt;             /* PPS calibration errors */
+    abi_long stbcnt;             /* PPS stability limit exceeded */
+    int tai;                     /* TAI offset */
+
+    /* Further padding bytes to allow for future expansion */
+    int:32; int:32; int:32; int:32;
+    int:32; int:32; int:32; int:32;
+    int:32; int:32; int:32;
+};
+
 typedef abi_long target_clock_t;
 
 #define TARGET_HZ 100
-- 
2.9.3

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

* [Qemu-devel] [PATCH v5 2/8] linux-user: Add support for clock_adjtime() syscall
  2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall Aleksandar Markovic
@ 2016-09-14 20:19 ` Aleksandar Markovic
  2016-09-17 22:41   ` Laurent Vivier
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 3/8] linux-user: Add support for sysfs() syscall Aleksandar Markovic
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:19 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

This patch implements Qemu user mode clock_adjtime() syscall support.

The implementation is based on invocation of host's clock_adjtime(), and is
very similar to the implementation of adjtimex() syscall support. The main
difference is the presence of "clockid_t" argument in clock_adjtime().

Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/strace.c    | 13 +++++++++++++
 linux-user/strace.list |  3 +++
 linux-user/syscall.c   | 19 ++++++++++++++++++-
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 7ddcaf8..4524c70 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -968,6 +968,19 @@ print_chmod(const struct syscallname *name,
 }
 #endif
 
+#ifdef TARGET_NR_clock_adjtime
+static void
+print_clock_adjtime(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+    print_raw_param("%d", arg0, 0);
+    print_pointer(arg1, 1);
+    print_syscall_epilogue(name);
+}
+#endif
+
 #ifdef TARGET_NR_clone
 static void do_print_clone(unsigned int flags, abi_ulong newsp,
                            abi_ulong parent_tidptr, target_ulong newtls,
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 9a665a8..00b2e9b 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -72,6 +72,9 @@
 #ifdef TARGET_NR_chroot
 { TARGET_NR_chroot, "chroot" , NULL, NULL, NULL },
 #endif
+#ifdef TARGET_NR_clock_adjtime
+{ TARGET_NR_clock_adjtime, "clock_adjtime" , NULL, print_clock_adjtime, NULL },
+#endif
 #ifdef TARGET_NR_clock_getres
 { TARGET_NR_clock_getres, "clock_getres" , NULL, NULL, NULL },
 #endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5643840..eab9207 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6579,7 +6579,7 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
 }
 #endif
 
-#ifdef TARGET_NR_adjtimex
+#if defined(TARGET_NR_adjtimex) || defined(TARGET_NR_clock_adjtime)
 static inline abi_long target_to_host_timex(struct timex *host_buf,
                                             abi_long target_addr)
 {
@@ -9509,6 +9509,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
+#ifdef TARGET_NR_clock_adjtime
+    case TARGET_NR_clock_adjtime:
+        {
+            struct timex host_buf;
+
+            if (target_to_host_timex(&host_buf, arg2) != 0) {
+                goto efault;
+            }
+            ret = get_errno(clock_adjtime(arg1, &host_buf));
+            if (!is_error(ret) && arg1) {
+                if (host_to_target_timex(arg2, &host_buf) != 0) {
+                    goto efault;
+                }
+            }
+        }
+        break;
+#endif
 #ifdef TARGET_NR_create_module
     case TARGET_NR_create_module:
 #endif
-- 
2.9.3

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

* [Qemu-devel] [PATCH v5 3/8] linux-user: Add support for sysfs() syscall
  2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall Aleksandar Markovic
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 2/8] linux-user: Add support for clock_adjtime() syscall Aleksandar Markovic
@ 2016-09-14 20:19 ` Aleksandar Markovic
  2016-09-17 23:28   ` Laurent Vivier
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 4/8] linux-user: Add support for ustat() syscall Aleksandar Markovic
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:19 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

This patch implements Qemu user mode sysfs() syscall support.

Syscall sysfs() involves returning information about the filesystem types
currently present in the kernel, and can operate in three distinct flavors,
depending on its first argument.

The implementation is based on invocation of host's sysfs(), and
its key part is in the correspondent case segment of the main switch
statement of the function do_syscall(), in file linux-user/syscalls.c.
All necessary conversions of data structures from target to host and from
host to target are covered. Based on the value of the first argument, three
cases are distinguished, and such conversions are implemented separately
for each case. Relevant support for "-strace" option is included in files
linux-user/strace.c and linux-user/strace.list.

This patch also fixes failures of LTP tests sysfs01, sysfs02, sysfs03,
sysfs04, sysfs05, and sysfs06, if executed in Qemu user mode.

Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/strace.c    | 25 +++++++++++++++++++++++++
 linux-user/strace.list |  2 +-
 linux-user/syscall.c   | 42 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 4524c70..61911e7 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -2151,6 +2151,31 @@ print_kill(const struct syscallname *name,
 }
 #endif
 
+#if defined(TARGET_NR_sysfs)
+static void
+print_sysfs(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+    switch (arg0) {
+    case 1:
+        print_raw_param("%d", arg0, 1);
+        print_string(arg1, 1);
+        break;
+    case 2:
+        print_raw_param("%d", arg0, 0);
+        print_raw_param("%u", arg1, 0);
+        print_pointer(arg2, 1);
+        break;
+    default:
+        print_raw_param("%d", arg0, 1);
+        break;
+    }
+    print_syscall_epilogue(name);
+}
+#endif
+
 /*
  * An array of all of the syscalls we know about
  */
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 00b2e9b..0bf1bea 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1371,7 +1371,7 @@
 { TARGET_NR_sys_epoll_wait, "sys_epoll_wait" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_sysfs
-{ TARGET_NR_sysfs, "sysfs" , NULL, NULL, NULL },
+{ TARGET_NR_sysfs, "sysfs" , NULL, print_sysfs, NULL },
 #endif
 #ifdef TARGET_NR_sysinfo
 { TARGET_NR_sysinfo, "sysinfo" , NULL, NULL, NULL },
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index eab9207..3436ee6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9549,7 +9549,47 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_sysfs
     case TARGET_NR_sysfs:
-        goto unimplemented;
+        switch (arg1) {
+        case 1:
+            {
+                if (arg2 != 0) {
+                    p = lock_user_string(arg2);
+                    if (!p) {
+                        goto efault;
+                    }
+                    ret = get_errno(syscall(__NR_sysfs, arg1, p));
+                    unlock_user(p, arg2, 0);
+                } else {
+                    ret = get_errno(syscall(__NR_sysfs, arg1, NULL));
+                }
+            }
+            break;
+        case 2:
+            {
+                if (arg3 != 0) {
+                    char buf[PATH_MAX];
+                    int len;
+                    memset(buf, 0, PATH_MAX);
+                    ret = get_errno(syscall(__NR_sysfs, arg1, arg2, buf));
+                    len = PATH_MAX;
+                    if (len > strlen(buf)) {
+                        len = strlen(buf);
+                    }
+                    if (copy_to_user(arg3, buf, len) != 0) {
+                        goto efault;
+                    }
+                } else {
+                    ret = get_errno(syscall(__NR_sysfs, arg1, arg2, NULL));
+                }
+            }
+            break;
+        case 3:
+            ret = get_errno(syscall(__NR_sysfs, arg1));
+            break;
+        default:
+            ret = -EINVAL;
+        }
+        break;
 #endif
     case TARGET_NR_personality:
         ret = get_errno(personality(arg1));
-- 
2.9.3

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

* [Qemu-devel] [PATCH v5 4/8] linux-user: Add support for ustat() syscall
  2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
                   ` (2 preceding siblings ...)
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 3/8] linux-user: Add support for sysfs() syscall Aleksandar Markovic
@ 2016-09-14 20:19 ` Aleksandar Markovic
  2016-09-17 23:39   ` Laurent Vivier
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 5/8] linux-user: Fix msgrcv() and msgsnd() syscalls support Aleksandar Markovic
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:19 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

This patch implements Qemu user mode ustat() syscall support.

Syscall ustat() returns information about a mounted filesystem.

The implementation is similar to the implementations of statfs(),
fstatfs() and other related syscalls. It is based on invocation of
host's ustat(), and its key part is in the correspondent case segment
of the main switch statement of the function do_syscall(), in file
linux-user/syscalls.c. All necessary conversions of data structures
from target to host and from host to target are covered. Sufficient
support for "-strace" option for this syscall is already present,
and this patch does not change it.

This patch also fixes failures of LTP tests ustat01, and ustat02, if
executed on Qemu-emulated systems.

Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/syscall.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3436ee6..7f8ae41 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -48,6 +48,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include <sys/shm.h>
 #include <sys/sem.h>
 #include <sys/statfs.h>
+#include <ustat.h>
 #include <utime.h>
 #include <sys/sysinfo.h>
 #include <sys/signalfd.h>
@@ -8098,7 +8099,29 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #ifdef TARGET_NR_ustat
     case TARGET_NR_ustat:
-        goto unimplemented;
+    {
+        struct ustat ust;
+        int cnt;
+        ret = get_errno(ustat(arg1, &ust));
+
+        if (!is_error(ret)) {
+            struct ustat *target_ust;
+
+            if (!lock_user_struct(VERIFY_WRITE, target_ust, arg2, 0)) {
+                goto efault;
+            }
+
+            __put_user(ust.f_tfree, &target_ust->f_tfree);
+            __put_user(ust.f_tinode, &target_ust->f_tinode);
+
+            for (cnt = 0; cnt < 6; cnt++) {
+                __put_user(ust.f_fname[cnt], &target_ust->f_fname[cnt]);
+                __put_user(ust.f_fpack[cnt], &target_ust->f_fpack[cnt]);
+            }
+            unlock_user_struct(target_ust, arg2, 1);
+        }
+        break;
+      }
 #endif
 #ifdef TARGET_NR_dup2
     case TARGET_NR_dup2:
-- 
2.9.3

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

* [Qemu-devel] [PATCH v5 5/8] linux-user: Fix msgrcv() and msgsnd() syscalls support
  2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
                   ` (3 preceding siblings ...)
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 4/8] linux-user: Add support for ustat() syscall Aleksandar Markovic
@ 2016-09-14 20:19 ` Aleksandar Markovic
  2016-09-17 23:43   ` Laurent Vivier
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 6/8] linux-user: Fix socketcall() syscall support Aleksandar Markovic
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:19 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

If syscalls msgrcv() and msgsnd() fail, they return E2BIG, EACCES,
EAGAIN, EFAULT, EIDRM, EINTR, EINVAL, ENOMEM, or ENOMSG.

By examining negative scenarios of these syscalls for Mips, it was
established that ENOMSG does not have the same value accross all
platforms, but it is nevertheless not included for conversion in
the correspondant conversion table defined in linux-user/syscall.c.
This is certainly a bug, since it leads to the incorrect emulation
of msgrcv() and msgsnd() for scenarios involving ENOMSG.

This patch fixes this by extending the conversion table to include
ENOMSG.

Also, LTP test msgrcv04 will be fixed for some platforms.

Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/syscall.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7f8ae41..bdc12ae 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -750,6 +750,9 @@ static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
 #ifdef ENOTRECOVERABLE
     [ENOTRECOVERABLE]	= TARGET_ENOTRECOVERABLE,
 #endif
+#ifdef ENOMSG
+    [ENOMSG]            = TARGET_ENOMSG,
+#endif
 };
 
 static inline int host_to_target_errno(int err)
-- 
2.9.3

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

* [Qemu-devel] [PATCH v5 6/8] linux-user: Fix socketcall() syscall support
  2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
                   ` (4 preceding siblings ...)
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 5/8] linux-user: Fix msgrcv() and msgsnd() syscalls support Aleksandar Markovic
@ 2016-09-14 20:19 ` Aleksandar Markovic
  2016-09-18  0:02   ` Laurent Vivier
  2016-09-14 20:20 ` [Qemu-devel] [PATCH v5 7/8] linux-user: Fix syslog() " Aleksandar Markovic
  2016-09-14 20:20 ` [Qemu-devel] [PATCH v5 8/8] linux-user: Remove a duplicate item from strace.list Aleksandar Markovic
  7 siblings, 1 reply; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:19 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

do_socketcall() function in Qemu's syscalls.c is implemented to mirror
corespondant implementation of socketcall() in Linux kernel. (see kernel
source file net/socket.c, definition of socketcall).

However, error codes are wrong for the cases of invalid values of the first
argument. This patch in this sense brings do_socketcall() closer to its
kernel counterpart.

Also, this patch fixes failure of LTP test socketcall02, if executed on some
Qemu emulated sywstems (uer mode).

Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/syscall.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bdc12ae..4ffcce5 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3845,15 +3845,18 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
         [SOCKOP_getsockopt] = 5,  /* sockfd, level, optname, optval, optlen */
     };
     abi_long a[6]; /* max 6 args */
+    unsigned i;
 
-    /* first, collect the arguments in a[] according to ac[] */
-    if (num >= 0 && num < ARRAY_SIZE(ac)) {
-        unsigned i;
-        assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */
-        for (i = 0; i < ac[num]; ++i) {
-            if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
-                return -TARGET_EFAULT;
-            }
+    /* check the range of the first argument num */
+    if (num < 0 || num > ARRAY_SIZE(ac)) {
+        return -TARGET_EINVAL;
+    }
+
+    /* collect the arguments in a[] according to ac[] */
+    assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */
+    for (i = 0; i < ac[num]; ++i) {
+        if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
+            return -TARGET_EFAULT;
         }
     }
 
@@ -3901,7 +3904,7 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
         return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
     default:
         gemu_log("Unsupported socketcall: %d\n", num);
-        return -TARGET_ENOSYS;
+        return -TARGET_EINVAL;
     }
 }
 #endif
-- 
2.9.3

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

* [Qemu-devel] [PATCH v5 7/8] linux-user: Fix syslog() syscall support
  2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
                   ` (5 preceding siblings ...)
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 6/8] linux-user: Fix socketcall() syscall support Aleksandar Markovic
@ 2016-09-14 20:20 ` Aleksandar Markovic
  2016-09-18  0:38   ` Laurent Vivier
  2016-09-14 20:20 ` [Qemu-devel] [PATCH v5 8/8] linux-user: Remove a duplicate item from strace.list Aleksandar Markovic
  7 siblings, 1 reply; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:20 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

There are currently several problems related to syslog() support.

For example, if the second argument "bufp" of target syslog() syscall
is NULL, the current implementation always returns error code EFAULT.
However, NULL is a perfectly valid value for the second argument for
many use cases of this syscall. This is, for example, visible from
this excerpt of man page for syslog(2):

> EINVAL Bad arguments (e.g., bad type; or for type 2, 3, or 4, buf is
>        NULL, or len is less than zero; or for type 8, the level is
>        outside the range 1 to 8).

Moreover, the argument "bufp" is ignored for all cases of values of the
first argument, except 2, 3 and 4. This means that for such cases
(the first argument is not 2, 3 or 4), there is no need to pass "buf"
between host and target, and it can be set to NULL while calling host's
syslog(), without loss of emulation accuracy.

Note also that if "bufp" is NULL and the first argument is 2, 3 or 4, the
correct returned error code is EINVAL, not EFAULT.

All these details are reflected in this patch.

"#ifdef TARGET_NR_syslog" is also proprerly inserted when needed.

Support for Qemu's "-strace" switch for syslog() syscall is included too.

LTP tests syslog11 and syslog12 pass with this patch (while fail without
it), on any platform.

Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/strace.c       | 68 +++++++++++++++++++++++++++++++++++++++++++++++
 linux-user/strace.list    |  2 +-
 linux-user/syscall.c      | 23 +++++++++++-----
 linux-user/syscall_defs.h | 25 +++++++++++++++++
 4 files changed, 111 insertions(+), 7 deletions(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index 61911e7..6177f2c 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1709,6 +1709,74 @@ print_rt_sigprocmask(const struct syscallname *name,
 }
 #endif
 
+#ifdef TARGET_NR_syslog
+static void
+print_syslog_action(abi_ulong arg, int last)
+{
+    switch (arg) {
+        case TARGET_SYSLOG_ACTION_CLOSE: {
+            gemu_log("%s%s", "SYSLOG_ACTION_CLOSE", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_OPEN: {
+            gemu_log("%s%s", "SYSLOG_ACTION_OPEN", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_READ: {
+            gemu_log("%s%s", "SYSLOG_ACTION_READ", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_READ_ALL: {
+            gemu_log("%s%s", "SYSLOG_ACTION_READ_ALL", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_READ_CLEAR: {
+            gemu_log("%s%s", "SYSLOG_ACTION_READ_CLEAR", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_CLEAR: {
+            gemu_log("%s%s", "SYSLOG_ACTION_CLEAR", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_CONSOLE_OFF: {
+            gemu_log("%s%s", "SYSLOG_ACTION_CONSOLE_OFF", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_CONSOLE_ON: {
+            gemu_log("%s%s", "SYSLOG_ACTION_CONSOLE_ON", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_CONSOLE_LEVEL: {
+            gemu_log("%s%s", "SYSLOG_ACTION_CONSOLE_LEVEL", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_SIZE_UNREAD: {
+            gemu_log("%s%s", "SYSLOG_ACTION_SIZE_UNREAD", get_comma(last));
+            break;
+        }
+        case TARGET_SYSLOG_ACTION_SIZE_BUFFER: {
+            gemu_log("%s%s", "SYSLOG_ACTION_SIZE_BUFFER", get_comma(last));
+            break;
+        }
+        default: {
+            print_raw_param("%ld", arg, last);
+        }
+    }
+}
+
+static void
+print_syslog(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+    print_syslog_action(arg0, 0);
+    print_pointer(arg1, 0);
+    print_raw_param("%d", arg2, 1);
+    print_syscall_epilogue(name);
+}
+#endif
+
 #ifdef TARGET_NR_mknod
 static void
 print_mknod(const struct syscallname *name,
diff --git a/linux-user/strace.list b/linux-user/strace.list
index 0bf1bea..2f99ac2 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1380,7 +1380,7 @@
 { TARGET_NR_sys_kexec_load, "sys_kexec_load" , NULL, NULL, NULL },
 #endif
 #ifdef TARGET_NR_syslog
-{ TARGET_NR_syslog, "syslog" , NULL, NULL, NULL },
+{ TARGET_NR_syslog, "syslog" , NULL, print_syslog, NULL },
 #endif
 #ifdef TARGET_NR_sysmips
 { TARGET_NR_sysmips, "sysmips" , NULL, NULL, NULL },
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4ffcce5..37ce908 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9219,14 +9219,25 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
         break;
 #endif
-
+#ifdef TARGET_NR_syslog
     case TARGET_NR_syslog:
-        if (!(p = lock_user_string(arg2)))
-            goto efault;
-        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
-        unlock_user(p, arg2, 0);
+        {
+            if (((int)arg1 == TARGET_SYSLOG_ACTION_READ) ||
+                ((int)arg1 == TARGET_SYSLOG_ACTION_READ_ALL) ||
+                ((int)arg1 == TARGET_SYSLOG_ACTION_READ_CLEAR)) {
+                p = lock_user_string(arg2);
+                if (!p) {
+                    ret = -TARGET_EINVAL;
+                    goto fail;
+                }
+                ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
+                unlock_user(p, arg2, 0);
+            } else {
+                ret = get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
+            }
+        }
         break;
-
+#endif
     case TARGET_NR_setitimer:
         {
             struct itimerval value, ovalue, *pvalue;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index afd9191..50b1b60 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2661,4 +2661,29 @@ struct target_user_cap_data {
     uint32_t inheritable;
 };
 
+/* from kernel's include/linux/syslog.h */
+
+/* Close the log.  Currently a NOP. */
+#define TARGET_SYSLOG_ACTION_CLOSE          0
+/* Open the log. Currently a NOP. */
+#define TARGET_SYSLOG_ACTION_OPEN           1
+/* Read from the log. */
+#define TARGET_SYSLOG_ACTION_READ           2
+/* Read all messages remaining in the ring buffer. */
+#define TARGET_SYSLOG_ACTION_READ_ALL       3
+/* Read and clear all messages remaining in the ring buffer */
+#define TARGET_SYSLOG_ACTION_READ_CLEAR     4
+/* Clear ring buffer. */
+#define TARGET_SYSLOG_ACTION_CLEAR          5
+/* Disable printk's to console */
+#define TARGET_SYSLOG_ACTION_CONSOLE_OFF    6
+/* Enable printk's to console */
+#define TARGET_SYSLOG_ACTION_CONSOLE_ON     7
+/* Set level of messages printed to console */
+#define TARGET_SYSLOG_ACTION_CONSOLE_LEVEL  8
+/* Return number of unread characters in the log buffer */
+#define TARGET_SYSLOG_ACTION_SIZE_UNREAD    9
+/* Return size of the log buffer */
+#define TARGET_SYSLOG_ACTION_SIZE_BUFFER   10
+
 #endif
-- 
2.9.3

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

* [Qemu-devel] [PATCH v5 8/8] linux-user: Remove a duplicate item from strace.list
  2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
                   ` (6 preceding siblings ...)
  2016-09-14 20:20 ` [Qemu-devel] [PATCH v5 7/8] linux-user: Fix syslog() " Aleksandar Markovic
@ 2016-09-14 20:20 ` Aleksandar Markovic
  2016-09-18  0:13   ` Laurent Vivier
  7 siblings, 1 reply; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-14 20:20 UTC (permalink / raw)
  To: qemu-devel, riku.voipio, peter.maydell, petar.jovanovic,
	miodrag.dinic, aleksandar.rikalo, aleksandar.markovic

From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

There is a duplicate item in strace.list. It is benign, but it
shouldn't be there. It is the only duplicate in strace.list. This
patch removes it.

Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
 linux-user/strace.list | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/linux-user/strace.list b/linux-user/strace.list
index 2f99ac2..f74545f 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1532,9 +1532,6 @@
 #ifdef TARGET_NR_utimensat
 { TARGET_NR_utimensat, "utimensat", NULL, print_utimensat, NULL },
 #endif
-#ifdef TARGET_NR_sync_file_range
-{ TARGET_NR_sync_file_range, "sync_file_range", NULL, NULL, NULL },
-#endif
 #ifdef TARGET_NR_sync_file_range2
 { TARGET_NR_sync_file_range2, "sync_file_range2", NULL, NULL, NULL },
 #endif
-- 
2.9.3

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

* Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall Aleksandar Markovic
@ 2016-09-17 18:40   ` Laurent Vivier
  2016-09-17 22:38     ` Laurent Vivier
  2016-09-22  4:42   ` Riku Voipio
  1 sibling, 1 reply; 23+ messages in thread
From: Laurent Vivier @ 2016-09-17 18:40 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 14/09/2016 à 22:19, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> This patch implements Qemu user mode adjtimex() syscall support.
> 
> Syscall adjtimex() reads and optionally sets parameters for a clock
> adjustment algorithm used in network synchonization or similar scenarios.
> 
> The implementation is based on invocation of host's adjtimex(), and
> its key part is in the correspondent case segment of the main switch
> statement of the function do_syscall(), in file linux-user/syscalls.c.
> Also, support for related structure "timex" is added to the file
> linux-user/syscall_defs.h, based on its definition in Linux kernel. All
> necessary conversions of the data structures from target to host and from
> host to target are covered. Two new functions, target_to_host_timex() and
> host_to_target_timex(), are provided for the purpose of such conversions.
> Moreover, the relevant support for "-strace" Qemu option is included in
> files linux-user/strace.c and linux-user/strace.list.
> 
> This patch also fixes failures of LTP tests adjtimex01 and adjtimex02, if
> executed in Qemu user mode.
> 
> Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com>
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/strace.c       | 12 +++++++
>  linux-user/strace.list    |  2 +-
>  linux-user/syscall.c      | 90 ++++++++++++++++++++++++++++++++++++++++++++++-
>  linux-user/syscall_defs.h | 28 +++++++++++++++
>  4 files changed, 130 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index cc10dc4..7ddcaf8 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -919,6 +919,18 @@ print_access(const struct syscallname *name,
>  }
>  #endif
>  
> +#ifdef TARGET_NR_adjtimex
> +static void
> +print_adjtimex(const struct syscallname *name,
> +    abi_long arg0, abi_long arg1, abi_long arg2,
> +    abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +    print_syscall_prologue(name);
> +    print_pointer(arg0, 1);
> +    print_syscall_epilogue(name);
> +}
> +#endif
> +
>  #ifdef TARGET_NR_brk
>  static void
>  print_brk(const struct syscallname *name,
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index aa967a2..9a665a8 100644
> --- a/linux-user/strace.list
> +++ b/linux-user/strace.list
> @@ -16,7 +16,7 @@
>  { TARGET_NR_add_key, "add_key" , NULL, NULL, NULL },
>  #endif
>  #ifdef TARGET_NR_adjtimex
> -{ TARGET_NR_adjtimex, "adjtimex" , NULL, NULL, NULL },
> +{ TARGET_NR_adjtimex, "adjtimex" , NULL, print_adjtimex, NULL },
>  #endif
>  #ifdef TARGET_NR_afs_syscall
>  { TARGET_NR_afs_syscall, "afs_syscall" , NULL, NULL, NULL },
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ca06943..5643840 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -35,6 +35,7 @@
>  #include <sys/swap.h>
>  #include <linux/capability.h>
>  #include <sched.h>
> +#include <sys/timex.h>
>  #ifdef __ia64__
>  int __clone2(int (*fn)(void *), void *child_stack_base,
>               size_t stack_size, int flags, void *arg, ...);
> @@ -6578,6 +6579,78 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
>  }
>  #endif
>  
> +#ifdef TARGET_NR_adjtimex
> +static inline abi_long target_to_host_timex(struct timex *host_buf,
> +                                            abi_long target_addr)
> +{
> +    struct target_timex *target_buf;

target_tx instead of target_buf would be nicer(?)

> +
> +    if (!lock_user_struct(VERIFY_READ, target_buf, target_addr, 1)) {
> +        return -TARGET_EFAULT;
> +    }
> +
> +    host_buf->modes = tswap32(target_buf->modes);
> +    host_buf->offset = tswapal(target_buf->offset);
> +    host_buf->freq = tswapal(target_buf->freq);
> +    host_buf->maxerror = tswapal(target_buf->maxerror);
> +    host_buf->esterror = tswapal(target_buf->esterror);
> +    host_buf->status = tswap32(target_buf->status);
> +    host_buf->constant = tswapal(target_buf->constant);
> +    host_buf->precision = tswapal(target_buf->precision);
> +    host_buf->tolerance = tswapal(target_buf->tolerance);
> +    host_buf->time.tv_sec = tswapal(target_buf->time.tv_sec);
> +    host_buf->time.tv_usec = tswapal(target_buf->time.tv_usec);
> +    host_buf->tick = tswapal(target_buf->tick);
> +    host_buf->ppsfreq = tswapal(target_buf->ppsfreq);
> +    host_buf->jitter = tswapal(target_buf->jitter);
> +    host_buf->shift = tswap32(target_buf->shift);
> +    host_buf->stabil = tswapal(target_buf->stabil);
> +    host_buf->jitcnt = tswapal(target_buf->jitcnt);
> +    host_buf->calcnt = tswapal(target_buf->calcnt);
> +    host_buf->errcnt = tswapal(target_buf->errcnt);
> +    host_buf->stbcnt = tswapal(target_buf->stbcnt);
> +    host_buf->tai = tswap32(target_buf->tai);

You should use __get_user(), see
c7e35da linux-user: Handle negative values in timespec conversion


> +
> +    unlock_user_struct(target_buf, target_addr, 0);
> +    return 0;
> +}
> +
> +static inline abi_long host_to_target_timex(abi_long target_addr,
> +                                            struct timex *host_buf)
> +{
> +    struct target_timex *target_buf;

target_tx?

> +
> +    if (!lock_user_struct(VERIFY_WRITE, target_buf, target_addr, 0)) {
> +        return -TARGET_EFAULT;
> +    }
> +
> +    target_buf->modes = tswap32(host_buf->modes);
> +    target_buf->offset = tswapal(host_buf->offset);
> +    target_buf->freq = tswapal(host_buf->freq);
> +    target_buf->maxerror = tswapal(host_buf->maxerror);
> +    target_buf->esterror = tswapal(host_buf->esterror);
> +    target_buf->status = tswap32(host_buf->status);
> +    target_buf->constant = tswapal(host_buf->constant);
> +    target_buf->precision = tswapal(host_buf->precision);
> +    target_buf->tolerance = tswapal(host_buf->tolerance);
> +    target_buf->time.tv_sec = tswapal(host_buf->time.tv_sec);
> +    target_buf->time.tv_usec = tswapal(host_buf->time.tv_usec);
> +    target_buf->tick = tswapal(host_buf->tick);
> +    target_buf->ppsfreq = tswapal(host_buf->ppsfreq);
> +    target_buf->jitter = tswapal(host_buf->jitter);
> +    target_buf->shift = tswap32(host_buf->shift);
> +    target_buf->stabil = tswapal(host_buf->stabil);
> +    target_buf->jitcnt = tswapal(host_buf->jitcnt);
> +    target_buf->calcnt = tswapal(host_buf->calcnt);
> +    target_buf->errcnt = tswapal(host_buf->errcnt);
> +    target_buf->stbcnt = tswapal(host_buf->stbcnt);
> +    target_buf->tai = tswap32(host_buf->tai);

I think you should use __put_user()...

> +    unlock_user_struct(target_buf, target_addr, 1);
> +    return 0;
> +}
> +#endif
> +
>  static inline abi_long target_to_host_timespec(struct timespec *host_ts,
>                                                 abi_ulong target_addr)
>  {
> @@ -9419,8 +9492,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          break;
>  #endif
>  #endif
> +#ifdef TARGET_NR_adjtimex
>      case TARGET_NR_adjtimex:
> -        goto unimplemented;
> +        {
> +            struct timex host_buf;
> +

check arg1 != NULL, so you manage target_to_host and host_to_target NULL
case.

> +            if (target_to_host_timex(&host_buf, arg1) != 0) {
> +                goto efault;
> +            }
> +            ret = get_errno(adjtimex(&host_buf));
> +            if (!is_error(ret) && arg1) {
> +                if (host_to_target_timex(arg1, &host_buf) != 0) {
> +                    goto efault;
> +                }
> +            }
> +        }
> +        break;
> +#endif
>  #ifdef TARGET_NR_create_module
>      case TARGET_NR_create_module:
>  #endif
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 7835654..afd9191 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -207,6 +207,34 @@ struct target_itimerspec {
>      struct target_timespec it_value;
>  };
>  
> +struct target_timex {
> +    unsigned int modes;          /* Mode selector */
> +    abi_long offset;             /* Time offset */
> +    abi_long freq;               /* Frequency offset */
> +    abi_long maxerror;           /* Maximum error (microseconds) */
> +    abi_long esterror;           /* Estimated error (microseconds) */
> +    int status;                  /* Clock command/status */
> +    abi_long constant;           /* PLL (phase-locked loop) time constant */
> +    abi_long precision;          /* Clock precision (microseconds, ro) */
> +    abi_long tolerance;          /* Clock freq. tolerance (ppm, ro) */
> +    struct target_timeval time;  /* Current time */
> +    abi_long tick;               /* Microseconds between clock ticks */
> +    abi_long ppsfreq;            /* PPS (pulse per second) frequency */
> +    abi_long jitter;             /* PPS jitter (ro); nanoseconds */
> +    int shift;                   /* PPS interval duration (seconds) */
> +    abi_long stabil;             /* PPS stability */
> +    abi_long jitcnt;             /* PPS jitter limit exceeded (ro) */
> +    abi_long calcnt;             /* PPS calibration intervals */
> +    abi_long errcnt;             /* PPS calibration errors */
> +    abi_long stbcnt;             /* PPS stability limit exceeded */
> +    int tai;                     /* TAI offset */
> +
> +    /* Further padding bytes to allow for future expansion */
> +    int:32; int:32; int:32; int:32;
> +    int:32; int:32; int:32; int:32;
> +    int:32; int:32; int:32;
> +};
> +

for the alignment purpose, use abi_uint/abi_int instead of uint/int.

>  typedef abi_long target_clock_t;
>  
>  #define TARGET_HZ 100
> 

Thanks,
Laurent

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

* Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
  2016-09-17 18:40   ` Laurent Vivier
@ 2016-09-17 22:38     ` Laurent Vivier
  0 siblings, 0 replies; 23+ messages in thread
From: Laurent Vivier @ 2016-09-17 22:38 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 17/09/2016 à 20:40, Laurent Vivier a écrit :
> 
> 
> Le 14/09/2016 à 22:19, Aleksandar Markovic a écrit :

>>  static inline abi_long target_to_host_timespec(struct timespec *host_ts,
>>                                                 abi_ulong target_addr)
>>  {
>> @@ -9419,8 +9492,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>>          break;
>>  #endif
>>  #endif
>> +#ifdef TARGET_NR_adjtimex
>>      case TARGET_NR_adjtimex:
>> -        goto unimplemented;
>> +        {
>> +            struct timex host_buf;
>> +
> 
> check arg1 != NULL, so you manage target_to_host and host_to_target NULL
> case.

In fact, I think you should not check that, it will be managed by
lock_user_struct().

Laurent

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

* Re: [Qemu-devel] [PATCH v5 2/8] linux-user: Add support for clock_adjtime() syscall
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 2/8] linux-user: Add support for clock_adjtime() syscall Aleksandar Markovic
@ 2016-09-17 22:41   ` Laurent Vivier
  0 siblings, 0 replies; 23+ messages in thread
From: Laurent Vivier @ 2016-09-17 22:41 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 14/09/2016 à 22:19, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> This patch implements Qemu user mode clock_adjtime() syscall support.
> 
> The implementation is based on invocation of host's clock_adjtime(), and is
> very similar to the implementation of adjtimex() syscall support. The main
> difference is the presence of "clockid_t" argument in clock_adjtime().
> 
> Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com>
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/strace.c    | 13 +++++++++++++
>  linux-user/strace.list |  3 +++
>  linux-user/syscall.c   | 19 ++++++++++++++++++-
>  3 files changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index 7ddcaf8..4524c70 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -968,6 +968,19 @@ print_chmod(const struct syscallname *name,
>  }
>  #endif
>  
> +#ifdef TARGET_NR_clock_adjtime
> +static void
> +print_clock_adjtime(const struct syscallname *name,
> +    abi_long arg0, abi_long arg1, abi_long arg2,
> +    abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +    print_syscall_prologue(name);
> +    print_raw_param("%d", arg0, 0);
> +    print_pointer(arg1, 1);
> +    print_syscall_epilogue(name);
> +}
> +#endif
> +
>  #ifdef TARGET_NR_clone
>  static void do_print_clone(unsigned int flags, abi_ulong newsp,
>                             abi_ulong parent_tidptr, target_ulong newtls,
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index 9a665a8..00b2e9b 100644
> --- a/linux-user/strace.list
> +++ b/linux-user/strace.list
> @@ -72,6 +72,9 @@
>  #ifdef TARGET_NR_chroot
>  { TARGET_NR_chroot, "chroot" , NULL, NULL, NULL },
>  #endif
> +#ifdef TARGET_NR_clock_adjtime
> +{ TARGET_NR_clock_adjtime, "clock_adjtime" , NULL, print_clock_adjtime, NULL },
> +#endif
>  #ifdef TARGET_NR_clock_getres
>  { TARGET_NR_clock_getres, "clock_getres" , NULL, NULL, NULL },
>  #endif
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 5643840..eab9207 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -6579,7 +6579,7 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
>  }
>  #endif
>  
> -#ifdef TARGET_NR_adjtimex
> +#if defined(TARGET_NR_adjtimex) || defined(TARGET_NR_clock_adjtime)
>  static inline abi_long target_to_host_timex(struct timex *host_buf,
>                                              abi_long target_addr)
>  {
> @@ -9509,6 +9509,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          }
>          break;
>  #endif
> +#ifdef TARGET_NR_clock_adjtime
> +    case TARGET_NR_clock_adjtime:
> +        {
> +            struct timex host_buf;
> +
> +            if (target_to_host_timex(&host_buf, arg2) != 0) {
> +                goto efault;
> +            }
> +            ret = get_errno(clock_adjtime(arg1, &host_buf));
> +            if (!is_error(ret) && arg1) {

Why do you check arg1 here ?

> +                if (host_to_target_timex(arg2, &host_buf) != 0) {
> +                    goto efault;
> +                }
> +            }
> +        }
> +        break;
> +#endif
>  #ifdef TARGET_NR_create_module
>      case TARGET_NR_create_module:
>  #endif
> 

Laurent

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

* Re: [Qemu-devel] [PATCH v5 3/8] linux-user: Add support for sysfs() syscall
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 3/8] linux-user: Add support for sysfs() syscall Aleksandar Markovic
@ 2016-09-17 23:28   ` Laurent Vivier
  0 siblings, 0 replies; 23+ messages in thread
From: Laurent Vivier @ 2016-09-17 23:28 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 14/09/2016 à 22:19, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> This patch implements Qemu user mode sysfs() syscall support.
> 
> Syscall sysfs() involves returning information about the filesystem types
> currently present in the kernel, and can operate in three distinct flavors,
> depending on its first argument.
> 
> The implementation is based on invocation of host's sysfs(), and
> its key part is in the correspondent case segment of the main switch
> statement of the function do_syscall(), in file linux-user/syscalls.c.
> All necessary conversions of data structures from target to host and from
> host to target are covered. Based on the value of the first argument, three
> cases are distinguished, and such conversions are implemented separately
> for each case. Relevant support for "-strace" option is included in files
> linux-user/strace.c and linux-user/strace.list.
> 
> This patch also fixes failures of LTP tests sysfs01, sysfs02, sysfs03,
> sysfs04, sysfs05, and sysfs06, if executed in Qemu user mode.
> 
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/strace.c    | 25 +++++++++++++++++++++++++
>  linux-user/strace.list |  2 +-
>  linux-user/syscall.c   | 42 +++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 67 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index 4524c70..61911e7 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -2151,6 +2151,31 @@ print_kill(const struct syscallname *name,
>  }
>  #endif
>  
> +#if defined(TARGET_NR_sysfs)
> +static void
> +print_sysfs(const struct syscallname *name,
> +    abi_long arg0, abi_long arg1, abi_long arg2,
> +    abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +    print_syscall_prologue(name);

perhaps you can move here:

        print_raw_param("%d", arg0, 0);

> +    switch (arg0) {
> +    case 1:
> +        print_raw_param("%d", arg0, 1);

should be ", 0);"

> +        print_string(arg1, 1);
> +        break;
> +    case 2:
> +        print_raw_param("%d", arg0, 0);
> +        print_raw_param("%u", arg1, 0);
> +        print_pointer(arg2, 1);
> +        break;
> +    default:
> +        print_raw_param("%d", arg0, 1);
> +        break;

in syscall.c, you use 3 for this, and default is EINVAL.

> +    }
> +    print_syscall_epilogue(name);
> +}
> +#endif
> +
>  /*
>   * An array of all of the syscalls we know about
>   */
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index 00b2e9b..0bf1bea 100644
> --- a/linux-user/strace.list
> +++ b/linux-user/strace.list
> @@ -1371,7 +1371,7 @@
>  { TARGET_NR_sys_epoll_wait, "sys_epoll_wait" , NULL, NULL, NULL },
>  #endif
>  #ifdef TARGET_NR_sysfs
> -{ TARGET_NR_sysfs, "sysfs" , NULL, NULL, NULL },
> +{ TARGET_NR_sysfs, "sysfs" , NULL, print_sysfs, NULL },
>  #endif
>  #ifdef TARGET_NR_sysinfo
>  { TARGET_NR_sysinfo, "sysinfo" , NULL, NULL, NULL },
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index eab9207..3436ee6 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -9549,7 +9549,47 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>  #endif
>  #ifdef TARGET_NR_sysfs
>      case TARGET_NR_sysfs:
> -        goto unimplemented;
> +        switch (arg1) {
> +        case 1:
> +            {
> +                if (arg2 != 0) {

"arg2 == NULL" will be managed by lock_user_string()

> +                    p = lock_user_string(arg2);
> +                    if (!p) {
> +                        goto efault;
> +                    }
> +                    ret = get_errno(syscall(__NR_sysfs, arg1, p));
> +                    unlock_user(p, arg2, 0);
> +                } else {
> +                    ret = get_errno(syscall(__NR_sysfs, arg1, NULL));

why?

> +                }
> +            }
> +            break;
> +        case 2:
> +            {
> +                if (arg3 != 0) {
> +                    char buf[PATH_MAX];

PATH_MAX (4096) should be a little bit excessive for a filesystem name.
they have rarely more than 16 characters.

> +                    int len;
> +                    memset(buf, 0, PATH_MAX);
> +                    ret = get_errno(syscall(__NR_sysfs, arg1, arg2, buf));
> +                    len = PATH_MAX;
> +                    if (len > strlen(buf)) {
> +                        len = strlen(buf);
> +                    }
> +                    if (copy_to_user(arg3, buf, len) != 0) {
> +                        goto efault;
> +                    }
> +                } else {
> +                    ret = get_errno(syscall(__NR_sysfs, arg1, arg2, NULL));

Why?
just let the copy_to_user() trigger the "goto efault" in the case of
arg3 == 0.

> +                }
> +            }
> +            break;
> +        case 3:
> +            ret = get_errno(syscall(__NR_sysfs, arg1));
> +            break;
> +        default:
> +            ret = -EINVAL;
> +        }
> +        break;
>  #endif
>      case TARGET_NR_personality:
>          ret = get_errno(personality(arg1));
> 

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

* Re: [Qemu-devel] [PATCH v5 4/8] linux-user: Add support for ustat() syscall
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 4/8] linux-user: Add support for ustat() syscall Aleksandar Markovic
@ 2016-09-17 23:39   ` Laurent Vivier
  0 siblings, 0 replies; 23+ messages in thread
From: Laurent Vivier @ 2016-09-17 23:39 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 14/09/2016 à 22:19, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> This patch implements Qemu user mode ustat() syscall support.
> 
> Syscall ustat() returns information about a mounted filesystem.
> 
> The implementation is similar to the implementations of statfs(),
> fstatfs() and other related syscalls. It is based on invocation of
> host's ustat(), and its key part is in the correspondent case segment
> of the main switch statement of the function do_syscall(), in file
> linux-user/syscalls.c. All necessary conversions of data structures
> from target to host and from host to target are covered. Sufficient
> support for "-strace" option for this syscall is already present,
> and this patch does not change it.
> 
> This patch also fixes failures of LTP tests ustat01, and ustat02, if
> executed on Qemu-emulated systems.
> 
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/syscall.c | 25 ++++++++++++++++++++++++-
>  1 file changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 3436ee6..7f8ae41 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -48,6 +48,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
>  #include <sys/shm.h>
>  #include <sys/sem.h>
>  #include <sys/statfs.h>
> +#include <ustat.h>
>  #include <utime.h>
>  #include <sys/sysinfo.h>
>  #include <sys/signalfd.h>
> @@ -8098,7 +8099,29 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          break;
>  #ifdef TARGET_NR_ustat
>      case TARGET_NR_ustat:
> -        goto unimplemented;
> +    {
> +        struct ustat ust;
> +        int cnt;
> +        ret = get_errno(ustat(arg1, &ust));
> +
> +        if (!is_error(ret)) {
> +            struct ustat *target_ust;

You must define your own "struct target_ustat" as __kernel_daddr_t and
__kernel_ino_t are long (or int).

> +
> +            if (!lock_user_struct(VERIFY_WRITE, target_ust, arg2, 0)) {
> +                goto efault;
> +            }
> +
> +            __put_user(ust.f_tfree, &target_ust->f_tfree);
> +            __put_user(ust.f_tinode, &target_ust->f_tinode);
> +
> +            for (cnt = 0; cnt < 6; cnt++) {
> +                __put_user(ust.f_fname[cnt], &target_ust->f_fname[cnt]);
> +                __put_user(ust.f_fpack[cnt], &target_ust->f_fpack[cnt]);
> +            }

As the structure is locked and they are "char", you can do memcpy().

> +            unlock_user_struct(target_ust, arg2, 1);
> +        }
> +        break;
> +      }
>  #endif
>  #ifdef TARGET_NR_dup2
>      case TARGET_NR_dup2:
> 

Laurent

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

* Re: [Qemu-devel] [PATCH v5 5/8] linux-user: Fix msgrcv() and msgsnd() syscalls support
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 5/8] linux-user: Fix msgrcv() and msgsnd() syscalls support Aleksandar Markovic
@ 2016-09-17 23:43   ` Laurent Vivier
  2016-09-19 19:05     ` Aleksandar Markovic
  0 siblings, 1 reply; 23+ messages in thread
From: Laurent Vivier @ 2016-09-17 23:43 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 14/09/2016 à 22:19, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> If syscalls msgrcv() and msgsnd() fail, they return E2BIG, EACCES,
> EAGAIN, EFAULT, EIDRM, EINTR, EINVAL, ENOMEM, or ENOMSG.
> 
> By examining negative scenarios of these syscalls for Mips, it was
> established that ENOMSG does not have the same value accross all
> platforms, but it is nevertheless not included for conversion in
> the correspondant conversion table defined in linux-user/syscall.c.
> This is certainly a bug, since it leads to the incorrect emulation
> of msgrcv() and msgsnd() for scenarios involving ENOMSG.
> 
> This patch fixes this by extending the conversion table to include
> ENOMSG.
> 
> Also, LTP test msgrcv04 will be fixed for some platforms.
> 
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

Reviewed-by: Laurent Vivier <laurent@vivier.eu>

> ---
>  linux-user/syscall.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 7f8ae41..bdc12ae 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -750,6 +750,9 @@ static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
>  #ifdef ENOTRECOVERABLE
>      [ENOTRECOVERABLE]	= TARGET_ENOTRECOVERABLE,
>  #endif
> +#ifdef ENOMSG
> +    [ENOMSG]            = TARGET_ENOMSG,
> +#endif
>  };
>  
>  static inline int host_to_target_errno(int err)
> 

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

* Re: [Qemu-devel] [PATCH v5 6/8] linux-user: Fix socketcall() syscall support
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 6/8] linux-user: Fix socketcall() syscall support Aleksandar Markovic
@ 2016-09-18  0:02   ` Laurent Vivier
  0 siblings, 0 replies; 23+ messages in thread
From: Laurent Vivier @ 2016-09-18  0:02 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 14/09/2016 à 22:19, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> do_socketcall() function in Qemu's syscalls.c is implemented to mirror
> corespondant implementation of socketcall() in Linux kernel. (see kernel
> source file net/socket.c, definition of socketcall).
> 
> However, error codes are wrong for the cases of invalid values of the first
> argument. This patch in this sense brings do_socketcall() closer to its
> kernel counterpart.
> 
> Also, this patch fixes failure of LTP test socketcall02, if executed on some
> Qemu emulated sywstems (uer mode).
> 
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/syscall.c | 21 ++++++++++++---------
>  1 file changed, 12 insertions(+), 9 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index bdc12ae..4ffcce5 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -3845,15 +3845,18 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
>          [SOCKOP_getsockopt] = 5,  /* sockfd, level, optname, optval, optlen */
>      };
>      abi_long a[6]; /* max 6 args */
> +    unsigned i;
>  
> -    /* first, collect the arguments in a[] according to ac[] */
> -    if (num >= 0 && num < ARRAY_SIZE(ac)) {
> -        unsigned i;
> -        assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */
> -        for (i = 0; i < ac[num]; ++i) {
> -            if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
> -                return -TARGET_EFAULT;
> -            }
> +    /* check the range of the first argument num */
> +    if (num < 0 || num > ARRAY_SIZE(ac)) {
> +        return -TARGET_EINVAL;
> +    }

I'm not sure you can check this using the array index. kernel checks
against "num" value, i.e.:

    if (num < 1 || num > SOCKOP_sendmmsg) {
        return -TARGET_EINVAL;
    }


> +    /* collect the arguments in a[] according to ac[] */
> +    assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */

instead, do this like the kernel does:

    if (ac[num] > ARRAY_SIZE(a)) {
        return -TARGET_EINVAL;
    }

> +    for (i = 0; i < ac[num]; ++i) {
> +        if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {
> +            return -TARGET_EFAULT;
>          }
>      }
>  
> @@ -3901,7 +3904,7 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
>          return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);
>      default:
>          gemu_log("Unsupported socketcall: %d\n", num);
> -        return -TARGET_ENOSYS;
> +        return -TARGET_EINVAL;
>      }
>  }
>  #endif
> 

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

* Re: [Qemu-devel] [PATCH v5 8/8] linux-user: Remove a duplicate item from strace.list
  2016-09-14 20:20 ` [Qemu-devel] [PATCH v5 8/8] linux-user: Remove a duplicate item from strace.list Aleksandar Markovic
@ 2016-09-18  0:13   ` Laurent Vivier
  0 siblings, 0 replies; 23+ messages in thread
From: Laurent Vivier @ 2016-09-18  0:13 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 14/09/2016 à 22:20, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> There is a duplicate item in strace.list. It is benign, but it
> shouldn't be there. It is the only duplicate in strace.list. This
> patch removes it.
> 
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/strace.list | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index 2f99ac2..f74545f 100644
> --- a/linux-user/strace.list
> +++ b/linux-user/strace.list
> @@ -1532,9 +1532,6 @@
>  #ifdef TARGET_NR_utimensat
>  { TARGET_NR_utimensat, "utimensat", NULL, print_utimensat, NULL },
>  #endif
> -#ifdef TARGET_NR_sync_file_range
> -{ TARGET_NR_sync_file_range, "sync_file_range", NULL, NULL, NULL },
> -#endif
>  #ifdef TARGET_NR_sync_file_range2
>  { TARGET_NR_sync_file_range2, "sync_file_range2", NULL, NULL, NULL },
>  #endif
> 


You should remove the other one, as this one has been added when the
syscall has been implemented:

c727f47 linux-user: Implement sync_file_range{,2} syscalls

Laurent

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

* Re: [Qemu-devel] [PATCH v5 7/8] linux-user: Fix syslog() syscall support
  2016-09-14 20:20 ` [Qemu-devel] [PATCH v5 7/8] linux-user: Fix syslog() " Aleksandar Markovic
@ 2016-09-18  0:38   ` Laurent Vivier
  0 siblings, 0 replies; 23+ messages in thread
From: Laurent Vivier @ 2016-09-18  0:38 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel, riku.voipio, peter.maydell,
	petar.jovanovic, miodrag.dinic, aleksandar.rikalo,
	aleksandar.markovic



Le 14/09/2016 à 22:20, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> There are currently several problems related to syslog() support.
> 
> For example, if the second argument "bufp" of target syslog() syscall
> is NULL, the current implementation always returns error code EFAULT.
> However, NULL is a perfectly valid value for the second argument for
> many use cases of this syscall. This is, for example, visible from
> this excerpt of man page for syslog(2):
> 
>> EINVAL Bad arguments (e.g., bad type; or for type 2, 3, or 4, buf is
>>        NULL, or len is less than zero; or for type 8, the level is
>>        outside the range 1 to 8).
> 
> Moreover, the argument "bufp" is ignored for all cases of values of the
> first argument, except 2, 3 and 4. This means that for such cases
> (the first argument is not 2, 3 or 4), there is no need to pass "buf"
> between host and target, and it can be set to NULL while calling host's
> syslog(), without loss of emulation accuracy.
> 
> Note also that if "bufp" is NULL and the first argument is 2, 3 or 4, the
> correct returned error code is EINVAL, not EFAULT.
> 
> All these details are reflected in this patch.
> 
> "#ifdef TARGET_NR_syslog" is also proprerly inserted when needed.
> 
> Support for Qemu's "-strace" switch for syslog() syscall is included too.
> 
> LTP tests syslog11 and syslog12 pass with this patch (while fail without
> it), on any platform.
> 
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/strace.c       | 68 +++++++++++++++++++++++++++++++++++++++++++++++
>  linux-user/strace.list    |  2 +-
>  linux-user/syscall.c      | 23 +++++++++++-----
>  linux-user/syscall_defs.h | 25 +++++++++++++++++
>  4 files changed, 111 insertions(+), 7 deletions(-)
> 
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index 61911e7..6177f2c 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -1709,6 +1709,74 @@ print_rt_sigprocmask(const struct syscallname *name,
>  }
>  #endif
>  
> +#ifdef TARGET_NR_syslog
> +static void
> +print_syslog_action(abi_ulong arg, int last)
> +{

The double "%s" and duplicate gemu_log() are not really nice.

you can do:

    const char *type;

> +    switch (arg) {
> +        case TARGET_SYSLOG_ACTION_CLOSE: {
> +            gemu_log("%s%s", "SYSLOG_ACTION_CLOSE", get_comma(last));


        type = "SYSLOG_ACTION_CLOSE";
        break;
...
> +        default: {
> +            print_raw_param("%ld", arg, last);

               return;

> +        }
> +    }

    gemu_log(%s%s", type, get_comma(last));

> +}
> +
> +static void
> +print_syslog(const struct syscallname *name,
> +    abi_long arg0, abi_long arg1, abi_long arg2,
> +    abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +    print_syscall_prologue(name);
> +    print_syslog_action(arg0, 0);
> +    print_pointer(arg1, 0);
> +    print_raw_param("%d", arg2, 1);
> +    print_syscall_epilogue(name);
> +}
> +#endif
> +
>  #ifdef TARGET_NR_mknod
>  static void
>  print_mknod(const struct syscallname *name,
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index 0bf1bea..2f99ac2 100644
> --- a/linux-user/strace.list
> +++ b/linux-user/strace.list
> @@ -1380,7 +1380,7 @@
>  { TARGET_NR_sys_kexec_load, "sys_kexec_load" , NULL, NULL, NULL },
>  #endif
>  #ifdef TARGET_NR_syslog
> -{ TARGET_NR_syslog, "syslog" , NULL, NULL, NULL },
> +{ TARGET_NR_syslog, "syslog" , NULL, print_syslog, NULL },
>  #endif
>  #ifdef TARGET_NR_sysmips
>  { TARGET_NR_sysmips, "sysmips" , NULL, NULL, NULL },
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 4ffcce5..37ce908 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -9219,14 +9219,25 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
>          break;
>  #endif
> -
> +#ifdef TARGET_NR_syslog
>      case TARGET_NR_syslog:
> -        if (!(p = lock_user_string(arg2)))
> -            goto efault;
> -        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
> -        unlock_user(p, arg2, 0);
> +        {
> +            if (((int)arg1 == TARGET_SYSLOG_ACTION_READ) ||
> +                ((int)arg1 == TARGET_SYSLOG_ACTION_READ_ALL) ||
> +                ((int)arg1 == TARGET_SYSLOG_ACTION_READ_CLEAR)) {
> +                p = lock_user_string(arg2);

arg2 is empty. length is given by arg3.
Use lock_user(VERIFY_WRITE, arg2, arg3, 0) for that.

> +                if (!p) {
> +                    ret = -TARGET_EINVAL;
> +                    goto fail;
> +                }
> +                ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
> +                unlock_user(p, arg2, 0);

    unlock_user(p, arg2, arg3);

> +            } else {
> +                ret = get_errno(sys_syslog((int)arg1, NULL, (int)arg3));
> +            }
> +        }
>          break;
> -
> +#endif
>      case TARGET_NR_setitimer:
>          {
>              struct itimerval value, ovalue, *pvalue;
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index afd9191..50b1b60 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -2661,4 +2661,29 @@ struct target_user_cap_data {
>      uint32_t inheritable;
>  };
>  
> +/* from kernel's include/linux/syslog.h */
> +
> +/* Close the log.  Currently a NOP. */
> +#define TARGET_SYSLOG_ACTION_CLOSE          0
> +/* Open the log. Currently a NOP. */
> +#define TARGET_SYSLOG_ACTION_OPEN           1
> +/* Read from the log. */
> +#define TARGET_SYSLOG_ACTION_READ           2
> +/* Read all messages remaining in the ring buffer. */
> +#define TARGET_SYSLOG_ACTION_READ_ALL       3
> +/* Read and clear all messages remaining in the ring buffer */
> +#define TARGET_SYSLOG_ACTION_READ_CLEAR     4
> +/* Clear ring buffer. */
> +#define TARGET_SYSLOG_ACTION_CLEAR          5
> +/* Disable printk's to console */
> +#define TARGET_SYSLOG_ACTION_CONSOLE_OFF    6
> +/* Enable printk's to console */
> +#define TARGET_SYSLOG_ACTION_CONSOLE_ON     7
> +/* Set level of messages printed to console */
> +#define TARGET_SYSLOG_ACTION_CONSOLE_LEVEL  8
> +/* Return number of unread characters in the log buffer */
> +#define TARGET_SYSLOG_ACTION_SIZE_UNREAD    9
> +/* Return size of the log buffer */
> +#define TARGET_SYSLOG_ACTION_SIZE_BUFFER   10
> +
>  #endif
> 

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

* Re: [Qemu-devel] [PATCH v5 5/8] linux-user: Fix msgrcv() and msgsnd() syscalls support
  2016-09-17 23:43   ` Laurent Vivier
@ 2016-09-19 19:05     ` Aleksandar Markovic
  0 siblings, 0 replies; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-19 19:05 UTC (permalink / raw)
  To: Laurent Vivier, Aleksandar Markovic, qemu-devel, riku.voipio,
	peter.maydell, Petar Jovanovic, Miodrag Dinic, Aleksandar Rikalo

Hello, Lorain.

I really appreciate your reviewing these patches. This was a great opportunity for me to learn a lot. I will address all your concerns about this series in its next version, which is planned to be posted by the end of this week. Regarding another series on Mips-specific issues, its v7 was posted on qemu-devel today.

Thanks,
Aleksandar

________________________________________
From: Laurent Vivier [laurent@vivier.eu]
Sent: Saturday, September 17, 2016 4:43 PM
To: Aleksandar Markovic; qemu-devel@nongnu.org; riku.voipio@iki.fi; peter.maydell@linaro.org; Petar Jovanovic; Miodrag Dinic; Aleksandar Rikalo; Aleksandar Markovic
Subject: Re: [Qemu-devel] [PATCH v5 5/8] linux-user: Fix msgrcv() and msgsnd() syscalls support

Le 14/09/2016 à 22:19, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
>
> If syscalls msgrcv() and msgsnd() fail, they return E2BIG, EACCES,
> EAGAIN, EFAULT, EIDRM, EINTR, EINVAL, ENOMEM, or ENOMSG.
>
> By examining negative scenarios of these syscalls for Mips, it was
> established that ENOMSG does not have the same value accross all
> platforms, but it is nevertheless not included for conversion in
> the correspondant conversion table defined in linux-user/syscall.c.
> This is certainly a bug, since it leads to the incorrect emulation
> of msgrcv() and msgsnd() for scenarios involving ENOMSG.
>
> This patch fixes this by extending the conversion table to include
> ENOMSG.
>
> Also, LTP test msgrcv04 will be fixed for some platforms.
>
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>

Reviewed-by: Laurent Vivier <laurent@vivier.eu>

> ---
>  linux-user/syscall.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 7f8ae41..bdc12ae 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -750,6 +750,9 @@ static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
>  #ifdef ENOTRECOVERABLE
>      [ENOTRECOVERABLE]        = TARGET_ENOTRECOVERABLE,
>  #endif
> +#ifdef ENOMSG
> +    [ENOMSG]            = TARGET_ENOMSG,
> +#endif
>  };
>
>  static inline int host_to_target_errno(int err)
>

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

* Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
  2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall Aleksandar Markovic
  2016-09-17 18:40   ` Laurent Vivier
@ 2016-09-22  4:42   ` Riku Voipio
  2016-09-22  7:05     ` Aleksandar Markovic
  1 sibling, 1 reply; 23+ messages in thread
From: Riku Voipio @ 2016-09-22  4:42 UTC (permalink / raw)
  To: Aleksandar Markovic
  Cc: qemu-devel, peter.maydell, petar.jovanovic, miodrag.dinic,
	aleksandar.rikalo, aleksandar.markovic

On Wed, Sep 14, 2016 at 10:19:54PM +0200, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> 
> This patch implements Qemu user mode adjtimex() syscall support.
> 
> Syscall adjtimex() reads and optionally sets parameters for a clock
> adjustment algorithm used in network synchonization or similar scenarios.
> 
> The implementation is based on invocation of host's adjtimex(), and
> its key part is in the correspondent case segment of the main switch
> statement of the function do_syscall(), in file linux-user/syscalls.c.
> Also, support for related structure "timex" is added to the file
> linux-user/syscall_defs.h, based on its definition in Linux kernel. All
> necessary conversions of the data structures from target to host and from
> host to target are covered. Two new functions, target_to_host_timex() and
> host_to_target_timex(), are provided for the purpose of such conversions.
> Moreover, the relevant support for "-strace" Qemu option is included in
> files linux-user/strace.c and linux-user/strace.list.
> 
> This patch also fixes failures of LTP tests adjtimex01 and adjtimex02, if
> executed in Qemu user mode.
> 
> Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com>
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/strace.c       | 12 +++++++
>  linux-user/strace.list    |  2 +-
>  linux-user/syscall.c      | 90 ++++++++++++++++++++++++++++++++++++++++++++++-
>  linux-user/syscall_defs.h | 28 +++++++++++++++
>  4 files changed, 130 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index cc10dc4..7ddcaf8 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -919,6 +919,18 @@ print_access(const struct syscallname *name,
>  }
>  #endif
>  
> +#ifdef TARGET_NR_adjtimex

The ifdef isn't needed, all linux platorms support adjtimex.

> +static void
> +print_adjtimex(const struct syscallname *name,
> +    abi_long arg0, abi_long arg1, abi_long arg2,
> +    abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +    print_syscall_prologue(name);
> +    print_pointer(arg0, 1);
> +    print_syscall_epilogue(name);
> +}
> +#endif
> +
>  #ifdef TARGET_NR_brk
>  static void
>  print_brk(const struct syscallname *name,
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index aa967a2..9a665a8 100644
> --- a/linux-user/strace.list
> +++ b/linux-user/strace.list
> @@ -16,7 +16,7 @@
>  { TARGET_NR_add_key, "add_key" , NULL, NULL, NULL },
>  #endif
>  #ifdef TARGET_NR_adjtimex
> -{ TARGET_NR_adjtimex, "adjtimex" , NULL, NULL, NULL },
> +{ TARGET_NR_adjtimex, "adjtimex" , NULL, print_adjtimex, NULL },
>  #endif
>  #ifdef TARGET_NR_afs_syscall
>  { TARGET_NR_afs_syscall, "afs_syscall" , NULL, NULL, NULL },
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ca06943..5643840 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -35,6 +35,7 @@
>  #include <sys/swap.h>
>  #include <linux/capability.h>
>  #include <sched.h>
> +#include <sys/timex.h>
>  #ifdef __ia64__
>  int __clone2(int (*fn)(void *), void *child_stack_base,
>               size_t stack_size, int flags, void *arg, ...);
> @@ -6578,6 +6579,78 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
>  }
>  #endif
>  
> +#ifdef TARGET_NR_adjtimex
> +static inline abi_long target_to_host_timex(struct timex *host_buf,
> +                                            abi_long target_addr)
> +{
> +    struct target_timex *target_buf;
> +
> +    if (!lock_user_struct(VERIFY_READ, target_buf, target_addr, 1)) {
> +        return -TARGET_EFAULT;
> +    }
> +
> +    host_buf->modes = tswap32(target_buf->modes);
> +    host_buf->offset = tswapal(target_buf->offset);
> +    host_buf->freq = tswapal(target_buf->freq);
> +    host_buf->maxerror = tswapal(target_buf->maxerror);
> +    host_buf->esterror = tswapal(target_buf->esterror);
> +    host_buf->status = tswap32(target_buf->status);
> +    host_buf->constant = tswapal(target_buf->constant);
> +    host_buf->precision = tswapal(target_buf->precision);
> +    host_buf->tolerance = tswapal(target_buf->tolerance);
> +    host_buf->time.tv_sec = tswapal(target_buf->time.tv_sec);
> +    host_buf->time.tv_usec = tswapal(target_buf->time.tv_usec);
> +    host_buf->tick = tswapal(target_buf->tick);
> +    host_buf->ppsfreq = tswapal(target_buf->ppsfreq);
> +    host_buf->jitter = tswapal(target_buf->jitter);
> +    host_buf->shift = tswap32(target_buf->shift);
> +    host_buf->stabil = tswapal(target_buf->stabil);
> +    host_buf->jitcnt = tswapal(target_buf->jitcnt);
> +    host_buf->calcnt = tswapal(target_buf->calcnt);
> +    host_buf->errcnt = tswapal(target_buf->errcnt);
> +    host_buf->stbcnt = tswapal(target_buf->stbcnt);
> +    host_buf->tai = tswap32(target_buf->tai);
> +
> +    unlock_user_struct(target_buf, target_addr, 0);
> +    return 0;
> +}
> +
> +static inline abi_long host_to_target_timex(abi_long target_addr,
> +                                            struct timex *host_buf)
> +{
> +    struct target_timex *target_buf;
> +
> +    if (!lock_user_struct(VERIFY_WRITE, target_buf, target_addr, 0)) {
> +        return -TARGET_EFAULT;
> +    }
> +
> +    target_buf->modes = tswap32(host_buf->modes);
> +    target_buf->offset = tswapal(host_buf->offset);
> +    target_buf->freq = tswapal(host_buf->freq);
> +    target_buf->maxerror = tswapal(host_buf->maxerror);
> +    target_buf->esterror = tswapal(host_buf->esterror);
> +    target_buf->status = tswap32(host_buf->status);
> +    target_buf->constant = tswapal(host_buf->constant);
> +    target_buf->precision = tswapal(host_buf->precision);
> +    target_buf->tolerance = tswapal(host_buf->tolerance);
> +    target_buf->time.tv_sec = tswapal(host_buf->time.tv_sec);
> +    target_buf->time.tv_usec = tswapal(host_buf->time.tv_usec);
> +    target_buf->tick = tswapal(host_buf->tick);
> +    target_buf->ppsfreq = tswapal(host_buf->ppsfreq);
> +    target_buf->jitter = tswapal(host_buf->jitter);
> +    target_buf->shift = tswap32(host_buf->shift);
> +    target_buf->stabil = tswapal(host_buf->stabil);
> +    target_buf->jitcnt = tswapal(host_buf->jitcnt);
> +    target_buf->calcnt = tswapal(host_buf->calcnt);
> +    target_buf->errcnt = tswapal(host_buf->errcnt);
> +    target_buf->stbcnt = tswapal(host_buf->stbcnt);
> +    target_buf->tai = tswap32(host_buf->tai);
> +
> +    unlock_user_struct(target_buf, target_addr, 1);
> +    return 0;
> +}
> +#endif
> +
>  static inline abi_long target_to_host_timespec(struct timespec *host_ts,
>                                                 abi_ulong target_addr)
>  {
> @@ -9419,8 +9492,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          break;
>  #endif
>  #endif
> +#ifdef TARGET_NR_adjtimex
>      case TARGET_NR_adjtimex:
> -        goto unimplemented;
> +        {
> +            struct timex host_buf;
> +
> +            if (target_to_host_timex(&host_buf, arg1) != 0) {
> +                goto efault;
> +            }
> +            ret = get_errno(adjtimex(&host_buf));
> +            if (!is_error(ret) && arg1) {
> +                if (host_to_target_timex(arg1, &host_buf) != 0) {
> +                    goto efault;
> +                }
> +            }
> +        }
> +        break;
> +#endif
>  #ifdef TARGET_NR_create_module
>      case TARGET_NR_create_module:
>  #endif
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 7835654..afd9191 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -207,6 +207,34 @@ struct target_itimerspec {
>      struct target_timespec it_value;
>  };
>  
> +struct target_timex {
> +    unsigned int modes;          /* Mode selector */
> +    abi_long offset;             /* Time offset */
> +    abi_long freq;               /* Frequency offset */
> +    abi_long maxerror;           /* Maximum error (microseconds) */
> +    abi_long esterror;           /* Estimated error (microseconds) */
> +    int status;                  /* Clock command/status */
> +    abi_long constant;           /* PLL (phase-locked loop) time constant */
> +    abi_long precision;          /* Clock precision (microseconds, ro) */
> +    abi_long tolerance;          /* Clock freq. tolerance (ppm, ro) */
> +    struct target_timeval time;  /* Current time */
> +    abi_long tick;               /* Microseconds between clock ticks */
> +    abi_long ppsfreq;            /* PPS (pulse per second) frequency */
> +    abi_long jitter;             /* PPS jitter (ro); nanoseconds */
> +    int shift;                   /* PPS interval duration (seconds) */
> +    abi_long stabil;             /* PPS stability */
> +    abi_long jitcnt;             /* PPS jitter limit exceeded (ro) */
> +    abi_long calcnt;             /* PPS calibration intervals */
> +    abi_long errcnt;             /* PPS calibration errors */
> +    abi_long stbcnt;             /* PPS stability limit exceeded */
> +    int tai;                     /* TAI offset */
> +
> +    /* Further padding bytes to allow for future expansion */
> +    int:32; int:32; int:32; int:32;
> +    int:32; int:32; int:32; int:32;
> +    int:32; int:32; int:32;
> +};
> +
>  typedef abi_long target_clock_t;
>  
>  #define TARGET_HZ 100
> -- 
> 2.9.3
> 
> 

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

* Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
  2016-09-22  4:42   ` Riku Voipio
@ 2016-09-22  7:05     ` Aleksandar Markovic
  2016-09-22  8:12       ` Riku Voipio
  0 siblings, 1 reply; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-22  7:05 UTC (permalink / raw)
  To: Riku Voipio, Aleksandar Markovic
  Cc: qemu-devel, peter.maydell, Petar Jovanovic, Miodrag Dinic,
	Aleksandar Rikalo

Hi, Riku,

Thanks a lots for your review.

I have no problem deleting "#ifdef TARGET_NR_adjtimex" in strace.c.

However, I want to bring to your attention the case of future target Linux platforms seizing supporting adjtimex(). Let's say this reflects in such a way that TARGET_NR_adjtimex is not defined for such platform. Then we will have a compiler error that print_adjtimex() is unused. With "ifdef", we wouldn't.

Thanks,
Aleksandar

________________________________________
From: Riku Voipio [riku.voipio@iki.fi]
Sent: Wednesday, September 21, 2016 9:42 PM
To: Aleksandar Markovic
Cc: qemu-devel@nongnu.org; peter.maydell@linaro.org; Petar Jovanovic; Miodrag Dinic; Aleksandar Rikalo; Aleksandar Markovic
Subject: Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall

On Wed, Sep 14, 2016 at 10:19:54PM +0200, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
>
> This patch implements Qemu user mode adjtimex() syscall support.
>
> Syscall adjtimex() reads and optionally sets parameters for a clock
> adjustment algorithm used in network synchonization or similar scenarios.
>
> The implementation is based on invocation of host's adjtimex(), and
> its key part is in the correspondent case segment of the main switch
> statement of the function do_syscall(), in file linux-user/syscalls.c.
> Also, support for related structure "timex" is added to the file
> linux-user/syscall_defs.h, based on its definition in Linux kernel. All
> necessary conversions of the data structures from target to host and from
> host to target are covered. Two new functions, target_to_host_timex() and
> host_to_target_timex(), are provided for the purpose of such conversions.
> Moreover, the relevant support for "-strace" Qemu option is included in
> files linux-user/strace.c and linux-user/strace.list.
>
> This patch also fixes failures of LTP tests adjtimex01 and adjtimex02, if
> executed in Qemu user mode.
>
> Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com>
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> ---
>  linux-user/strace.c       | 12 +++++++
>  linux-user/strace.list    |  2 +-
>  linux-user/syscall.c      | 90 ++++++++++++++++++++++++++++++++++++++++++++++-
>  linux-user/syscall_defs.h | 28 +++++++++++++++
>  4 files changed, 130 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/strace.c b/linux-user/strace.c
> index cc10dc4..7ddcaf8 100644
> --- a/linux-user/strace.c
> +++ b/linux-user/strace.c
> @@ -919,6 +919,18 @@ print_access(const struct syscallname *name,
>  }
>  #endif
>
> +#ifdef TARGET_NR_adjtimex

The ifdef isn't needed, all linux platorms support adjtimex.

> +static void
> +print_adjtimex(const struct syscallname *name,
> +    abi_long arg0, abi_long arg1, abi_long arg2,
> +    abi_long arg3, abi_long arg4, abi_long arg5)
> +{
> +    print_syscall_prologue(name);
> +    print_pointer(arg0, 1);
> +    print_syscall_epilogue(name);
> +}
> +#endif
> +
>  #ifdef TARGET_NR_brk
>  static void
>  print_brk(const struct syscallname *name,
> diff --git a/linux-user/strace.list b/linux-user/strace.list
> index aa967a2..9a665a8 100644
> --- a/linux-user/strace.list
> +++ b/linux-user/strace.list
> @@ -16,7 +16,7 @@
>  { TARGET_NR_add_key, "add_key" , NULL, NULL, NULL },
>  #endif
>  #ifdef TARGET_NR_adjtimex
> -{ TARGET_NR_adjtimex, "adjtimex" , NULL, NULL, NULL },
> +{ TARGET_NR_adjtimex, "adjtimex" , NULL, print_adjtimex, NULL },
>  #endif
>  #ifdef TARGET_NR_afs_syscall
>  { TARGET_NR_afs_syscall, "afs_syscall" , NULL, NULL, NULL },
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ca06943..5643840 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -35,6 +35,7 @@
>  #include <sys/swap.h>
>  #include <linux/capability.h>
>  #include <sched.h>
> +#include <sys/timex.h>
>  #ifdef __ia64__
>  int __clone2(int (*fn)(void *), void *child_stack_base,
>               size_t stack_size, int flags, void *arg, ...);
> @@ -6578,6 +6579,78 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
>  }
>  #endif
>
> +#ifdef TARGET_NR_adjtimex
> +static inline abi_long target_to_host_timex(struct timex *host_buf,
> +                                            abi_long target_addr)
> +{
> +    struct target_timex *target_buf;
> +
> +    if (!lock_user_struct(VERIFY_READ, target_buf, target_addr, 1)) {
> +        return -TARGET_EFAULT;
> +    }
> +
> +    host_buf->modes = tswap32(target_buf->modes);
> +    host_buf->offset = tswapal(target_buf->offset);
> +    host_buf->freq = tswapal(target_buf->freq);
> +    host_buf->maxerror = tswapal(target_buf->maxerror);
> +    host_buf->esterror = tswapal(target_buf->esterror);
> +    host_buf->status = tswap32(target_buf->status);
> +    host_buf->constant = tswapal(target_buf->constant);
> +    host_buf->precision = tswapal(target_buf->precision);
> +    host_buf->tolerance = tswapal(target_buf->tolerance);
> +    host_buf->time.tv_sec = tswapal(target_buf->time.tv_sec);
> +    host_buf->time.tv_usec = tswapal(target_buf->time.tv_usec);
> +    host_buf->tick = tswapal(target_buf->tick);
> +    host_buf->ppsfreq = tswapal(target_buf->ppsfreq);
> +    host_buf->jitter = tswapal(target_buf->jitter);
> +    host_buf->shift = tswap32(target_buf->shift);
> +    host_buf->stabil = tswapal(target_buf->stabil);
> +    host_buf->jitcnt = tswapal(target_buf->jitcnt);
> +    host_buf->calcnt = tswapal(target_buf->calcnt);
> +    host_buf->errcnt = tswapal(target_buf->errcnt);
> +    host_buf->stbcnt = tswapal(target_buf->stbcnt);
> +    host_buf->tai = tswap32(target_buf->tai);
> +
> +    unlock_user_struct(target_buf, target_addr, 0);
> +    return 0;
> +}
> +
> +static inline abi_long host_to_target_timex(abi_long target_addr,
> +                                            struct timex *host_buf)
> +{
> +    struct target_timex *target_buf;
> +
> +    if (!lock_user_struct(VERIFY_WRITE, target_buf, target_addr, 0)) {
> +        return -TARGET_EFAULT;
> +    }
> +
> +    target_buf->modes = tswap32(host_buf->modes);
> +    target_buf->offset = tswapal(host_buf->offset);
> +    target_buf->freq = tswapal(host_buf->freq);
> +    target_buf->maxerror = tswapal(host_buf->maxerror);
> +    target_buf->esterror = tswapal(host_buf->esterror);
> +    target_buf->status = tswap32(host_buf->status);
> +    target_buf->constant = tswapal(host_buf->constant);
> +    target_buf->precision = tswapal(host_buf->precision);
> +    target_buf->tolerance = tswapal(host_buf->tolerance);
> +    target_buf->time.tv_sec = tswapal(host_buf->time.tv_sec);
> +    target_buf->time.tv_usec = tswapal(host_buf->time.tv_usec);
> +    target_buf->tick = tswapal(host_buf->tick);
> +    target_buf->ppsfreq = tswapal(host_buf->ppsfreq);
> +    target_buf->jitter = tswapal(host_buf->jitter);
> +    target_buf->shift = tswap32(host_buf->shift);
> +    target_buf->stabil = tswapal(host_buf->stabil);
> +    target_buf->jitcnt = tswapal(host_buf->jitcnt);
> +    target_buf->calcnt = tswapal(host_buf->calcnt);
> +    target_buf->errcnt = tswapal(host_buf->errcnt);
> +    target_buf->stbcnt = tswapal(host_buf->stbcnt);
> +    target_buf->tai = tswap32(host_buf->tai);
> +
> +    unlock_user_struct(target_buf, target_addr, 1);
> +    return 0;
> +}
> +#endif
> +
>  static inline abi_long target_to_host_timespec(struct timespec *host_ts,
>                                                 abi_ulong target_addr)
>  {
> @@ -9419,8 +9492,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>          break;
>  #endif
>  #endif
> +#ifdef TARGET_NR_adjtimex
>      case TARGET_NR_adjtimex:
> -        goto unimplemented;
> +        {
> +            struct timex host_buf;
> +
> +            if (target_to_host_timex(&host_buf, arg1) != 0) {
> +                goto efault;
> +            }
> +            ret = get_errno(adjtimex(&host_buf));
> +            if (!is_error(ret) && arg1) {
> +                if (host_to_target_timex(arg1, &host_buf) != 0) {
> +                    goto efault;
> +                }
> +            }
> +        }
> +        break;
> +#endif
>  #ifdef TARGET_NR_create_module
>      case TARGET_NR_create_module:
>  #endif
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 7835654..afd9191 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -207,6 +207,34 @@ struct target_itimerspec {
>      struct target_timespec it_value;
>  };
>
> +struct target_timex {
> +    unsigned int modes;          /* Mode selector */
> +    abi_long offset;             /* Time offset */
> +    abi_long freq;               /* Frequency offset */
> +    abi_long maxerror;           /* Maximum error (microseconds) */
> +    abi_long esterror;           /* Estimated error (microseconds) */
> +    int status;                  /* Clock command/status */
> +    abi_long constant;           /* PLL (phase-locked loop) time constant */
> +    abi_long precision;          /* Clock precision (microseconds, ro) */
> +    abi_long tolerance;          /* Clock freq. tolerance (ppm, ro) */
> +    struct target_timeval time;  /* Current time */
> +    abi_long tick;               /* Microseconds between clock ticks */
> +    abi_long ppsfreq;            /* PPS (pulse per second) frequency */
> +    abi_long jitter;             /* PPS jitter (ro); nanoseconds */
> +    int shift;                   /* PPS interval duration (seconds) */
> +    abi_long stabil;             /* PPS stability */
> +    abi_long jitcnt;             /* PPS jitter limit exceeded (ro) */
> +    abi_long calcnt;             /* PPS calibration intervals */
> +    abi_long errcnt;             /* PPS calibration errors */
> +    abi_long stbcnt;             /* PPS stability limit exceeded */
> +    int tai;                     /* TAI offset */
> +
> +    /* Further padding bytes to allow for future expansion */
> +    int:32; int:32; int:32; int:32;
> +    int:32; int:32; int:32; int:32;
> +    int:32; int:32; int:32;
> +};
> +
>  typedef abi_long target_clock_t;
>
>  #define TARGET_HZ 100
> --
> 2.9.3
>
>

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

* Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
  2016-09-22  7:05     ` Aleksandar Markovic
@ 2016-09-22  8:12       ` Riku Voipio
  2016-09-22 12:28         ` Aleksandar Markovic
  0 siblings, 1 reply; 23+ messages in thread
From: Riku Voipio @ 2016-09-22  8:12 UTC (permalink / raw)
  To: Aleksandar Markovic
  Cc: Aleksandar Markovic, qemu-devel, peter.maydell, Petar Jovanovic,
	Miodrag Dinic, Aleksandar Rikalo

On Thu, Sep 22, 2016 at 07:05:11AM +0000, Aleksandar Markovic wrote:
> Hi, Riku,
> 
> Thanks a lots for your review.
> 
> I have no problem deleting "#ifdef TARGET_NR_adjtimex" in strace.c.
> 
> However, I want to bring to your attention the case of future target Linux platforms seizing supporting adjtimex(). Let's say this reflects in such a way that TARGET_NR_adjtimex is not defined for such platform. Then we will have a compiler error that print_adjtimex() is unused. With "ifdef", we wouldn't.
> 

To add a new plaform to qemu, changes to the code are needed anyways, so
adding an ifdef then isn't a problem. The #ifdef TARGET_NR_ guards are
useful for 1) legacy syscalls that new platforms don't support, or 2) new
syscalls that old platforms don't support (yet). adjtimex may be deprecated
on day, but even the new platforms (aarch64, ppc64le) have opted to support
it.

> Thanks,
> Aleksandar
> 
> ________________________________________
> From: Riku Voipio [riku.voipio@iki.fi]
> Sent: Wednesday, September 21, 2016 9:42 PM
> To: Aleksandar Markovic
> Cc: qemu-devel@nongnu.org; peter.maydell@linaro.org; Petar Jovanovic; Miodrag Dinic; Aleksandar Rikalo; Aleksandar Markovic
> Subject: Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
> 
> On Wed, Sep 14, 2016 at 10:19:54PM +0200, Aleksandar Markovic wrote:
> > From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> >
> > This patch implements Qemu user mode adjtimex() syscall support.
> >
> > Syscall adjtimex() reads and optionally sets parameters for a clock
> > adjustment algorithm used in network synchonization or similar scenarios.
> >
> > The implementation is based on invocation of host's adjtimex(), and
> > its key part is in the correspondent case segment of the main switch
> > statement of the function do_syscall(), in file linux-user/syscalls.c.
> > Also, support for related structure "timex" is added to the file
> > linux-user/syscall_defs.h, based on its definition in Linux kernel. All
> > necessary conversions of the data structures from target to host and from
> > host to target are covered. Two new functions, target_to_host_timex() and
> > host_to_target_timex(), are provided for the purpose of such conversions.
> > Moreover, the relevant support for "-strace" Qemu option is included in
> > files linux-user/strace.c and linux-user/strace.list.
> >
> > This patch also fixes failures of LTP tests adjtimex01 and adjtimex02, if
> > executed in Qemu user mode.
> >
> > Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com>
> > Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> > ---
> >  linux-user/strace.c       | 12 +++++++
> >  linux-user/strace.list    |  2 +-
> >  linux-user/syscall.c      | 90 ++++++++++++++++++++++++++++++++++++++++++++++-
> >  linux-user/syscall_defs.h | 28 +++++++++++++++
> >  4 files changed, 130 insertions(+), 2 deletions(-)
> >
> > diff --git a/linux-user/strace.c b/linux-user/strace.c
> > index cc10dc4..7ddcaf8 100644
> > --- a/linux-user/strace.c
> > +++ b/linux-user/strace.c
> > @@ -919,6 +919,18 @@ print_access(const struct syscallname *name,
> >  }
> >  #endif
> >
> > +#ifdef TARGET_NR_adjtimex
> 
> The ifdef isn't needed, all linux platorms support adjtimex.
> 
> > +static void
> > +print_adjtimex(const struct syscallname *name,
> > +    abi_long arg0, abi_long arg1, abi_long arg2,
> > +    abi_long arg3, abi_long arg4, abi_long arg5)
> > +{
> > +    print_syscall_prologue(name);
> > +    print_pointer(arg0, 1);
> > +    print_syscall_epilogue(name);
> > +}
> > +#endif
> > +
> >  #ifdef TARGET_NR_brk
> >  static void
> >  print_brk(const struct syscallname *name,
> > diff --git a/linux-user/strace.list b/linux-user/strace.list
> > index aa967a2..9a665a8 100644
> > --- a/linux-user/strace.list
> > +++ b/linux-user/strace.list
> > @@ -16,7 +16,7 @@
> >  { TARGET_NR_add_key, "add_key" , NULL, NULL, NULL },
> >  #endif
> >  #ifdef TARGET_NR_adjtimex
> > -{ TARGET_NR_adjtimex, "adjtimex" , NULL, NULL, NULL },
> > +{ TARGET_NR_adjtimex, "adjtimex" , NULL, print_adjtimex, NULL },
> >  #endif
> >  #ifdef TARGET_NR_afs_syscall
> >  { TARGET_NR_afs_syscall, "afs_syscall" , NULL, NULL, NULL },
> > diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> > index ca06943..5643840 100644
> > --- a/linux-user/syscall.c
> > +++ b/linux-user/syscall.c
> > @@ -35,6 +35,7 @@
> >  #include <sys/swap.h>
> >  #include <linux/capability.h>
> >  #include <sched.h>
> > +#include <sys/timex.h>
> >  #ifdef __ia64__
> >  int __clone2(int (*fn)(void *), void *child_stack_base,
> >               size_t stack_size, int flags, void *arg, ...);
> > @@ -6578,6 +6579,78 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
> >  }
> >  #endif
> >
> > +#ifdef TARGET_NR_adjtimex
> > +static inline abi_long target_to_host_timex(struct timex *host_buf,
> > +                                            abi_long target_addr)
> > +{
> > +    struct target_timex *target_buf;
> > +
> > +    if (!lock_user_struct(VERIFY_READ, target_buf, target_addr, 1)) {
> > +        return -TARGET_EFAULT;
> > +    }
> > +
> > +    host_buf->modes = tswap32(target_buf->modes);
> > +    host_buf->offset = tswapal(target_buf->offset);
> > +    host_buf->freq = tswapal(target_buf->freq);
> > +    host_buf->maxerror = tswapal(target_buf->maxerror);
> > +    host_buf->esterror = tswapal(target_buf->esterror);
> > +    host_buf->status = tswap32(target_buf->status);
> > +    host_buf->constant = tswapal(target_buf->constant);
> > +    host_buf->precision = tswapal(target_buf->precision);
> > +    host_buf->tolerance = tswapal(target_buf->tolerance);
> > +    host_buf->time.tv_sec = tswapal(target_buf->time.tv_sec);
> > +    host_buf->time.tv_usec = tswapal(target_buf->time.tv_usec);
> > +    host_buf->tick = tswapal(target_buf->tick);
> > +    host_buf->ppsfreq = tswapal(target_buf->ppsfreq);
> > +    host_buf->jitter = tswapal(target_buf->jitter);
> > +    host_buf->shift = tswap32(target_buf->shift);
> > +    host_buf->stabil = tswapal(target_buf->stabil);
> > +    host_buf->jitcnt = tswapal(target_buf->jitcnt);
> > +    host_buf->calcnt = tswapal(target_buf->calcnt);
> > +    host_buf->errcnt = tswapal(target_buf->errcnt);
> > +    host_buf->stbcnt = tswapal(target_buf->stbcnt);
> > +    host_buf->tai = tswap32(target_buf->tai);
> > +
> > +    unlock_user_struct(target_buf, target_addr, 0);
> > +    return 0;
> > +}
> > +
> > +static inline abi_long host_to_target_timex(abi_long target_addr,
> > +                                            struct timex *host_buf)
> > +{
> > +    struct target_timex *target_buf;
> > +
> > +    if (!lock_user_struct(VERIFY_WRITE, target_buf, target_addr, 0)) {
> > +        return -TARGET_EFAULT;
> > +    }
> > +
> > +    target_buf->modes = tswap32(host_buf->modes);
> > +    target_buf->offset = tswapal(host_buf->offset);
> > +    target_buf->freq = tswapal(host_buf->freq);
> > +    target_buf->maxerror = tswapal(host_buf->maxerror);
> > +    target_buf->esterror = tswapal(host_buf->esterror);
> > +    target_buf->status = tswap32(host_buf->status);
> > +    target_buf->constant = tswapal(host_buf->constant);
> > +    target_buf->precision = tswapal(host_buf->precision);
> > +    target_buf->tolerance = tswapal(host_buf->tolerance);
> > +    target_buf->time.tv_sec = tswapal(host_buf->time.tv_sec);
> > +    target_buf->time.tv_usec = tswapal(host_buf->time.tv_usec);
> > +    target_buf->tick = tswapal(host_buf->tick);
> > +    target_buf->ppsfreq = tswapal(host_buf->ppsfreq);
> > +    target_buf->jitter = tswapal(host_buf->jitter);
> > +    target_buf->shift = tswap32(host_buf->shift);
> > +    target_buf->stabil = tswapal(host_buf->stabil);
> > +    target_buf->jitcnt = tswapal(host_buf->jitcnt);
> > +    target_buf->calcnt = tswapal(host_buf->calcnt);
> > +    target_buf->errcnt = tswapal(host_buf->errcnt);
> > +    target_buf->stbcnt = tswapal(host_buf->stbcnt);
> > +    target_buf->tai = tswap32(host_buf->tai);
> > +
> > +    unlock_user_struct(target_buf, target_addr, 1);
> > +    return 0;
> > +}
> > +#endif
> > +
> >  static inline abi_long target_to_host_timespec(struct timespec *host_ts,
> >                                                 abi_ulong target_addr)
> >  {
> > @@ -9419,8 +9492,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> >          break;
> >  #endif
> >  #endif
> > +#ifdef TARGET_NR_adjtimex
> >      case TARGET_NR_adjtimex:
> > -        goto unimplemented;
> > +        {
> > +            struct timex host_buf;
> > +
> > +            if (target_to_host_timex(&host_buf, arg1) != 0) {
> > +                goto efault;
> > +            }
> > +            ret = get_errno(adjtimex(&host_buf));
> > +            if (!is_error(ret) && arg1) {
> > +                if (host_to_target_timex(arg1, &host_buf) != 0) {
> > +                    goto efault;
> > +                }
> > +            }
> > +        }
> > +        break;
> > +#endif
> >  #ifdef TARGET_NR_create_module
> >      case TARGET_NR_create_module:
> >  #endif
> > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> > index 7835654..afd9191 100644
> > --- a/linux-user/syscall_defs.h
> > +++ b/linux-user/syscall_defs.h
> > @@ -207,6 +207,34 @@ struct target_itimerspec {
> >      struct target_timespec it_value;
> >  };
> >
> > +struct target_timex {
> > +    unsigned int modes;          /* Mode selector */
> > +    abi_long offset;             /* Time offset */
> > +    abi_long freq;               /* Frequency offset */
> > +    abi_long maxerror;           /* Maximum error (microseconds) */
> > +    abi_long esterror;           /* Estimated error (microseconds) */
> > +    int status;                  /* Clock command/status */
> > +    abi_long constant;           /* PLL (phase-locked loop) time constant */
> > +    abi_long precision;          /* Clock precision (microseconds, ro) */
> > +    abi_long tolerance;          /* Clock freq. tolerance (ppm, ro) */
> > +    struct target_timeval time;  /* Current time */
> > +    abi_long tick;               /* Microseconds between clock ticks */
> > +    abi_long ppsfreq;            /* PPS (pulse per second) frequency */
> > +    abi_long jitter;             /* PPS jitter (ro); nanoseconds */
> > +    int shift;                   /* PPS interval duration (seconds) */
> > +    abi_long stabil;             /* PPS stability */
> > +    abi_long jitcnt;             /* PPS jitter limit exceeded (ro) */
> > +    abi_long calcnt;             /* PPS calibration intervals */
> > +    abi_long errcnt;             /* PPS calibration errors */
> > +    abi_long stbcnt;             /* PPS stability limit exceeded */
> > +    int tai;                     /* TAI offset */
> > +
> > +    /* Further padding bytes to allow for future expansion */
> > +    int:32; int:32; int:32; int:32;
> > +    int:32; int:32; int:32; int:32;
> > +    int:32; int:32; int:32;
> > +};
> > +
> >  typedef abi_long target_clock_t;
> >
> >  #define TARGET_HZ 100
> > --
> > 2.9.3
> >
> >

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

* Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
  2016-09-22  8:12       ` Riku Voipio
@ 2016-09-22 12:28         ` Aleksandar Markovic
  0 siblings, 0 replies; 23+ messages in thread
From: Aleksandar Markovic @ 2016-09-22 12:28 UTC (permalink / raw)
  To: Riku Voipio
  Cc: Aleksandar Markovic, qemu-devel, peter.maydell, Petar Jovanovic,
	Miodrag Dinic, Aleksandar Rikalo

Hi, Riku,

I really appreciate your clarification. I am going to address your concern in the next version of this series, which is planned to be posted in a short time.

Thank,
Aleksandar

________________________________________
From: Riku Voipio [riku.voipio@iki.fi]
Sent: Thursday, September 22, 2016 1:12 AM
To: Aleksandar Markovic
Cc: Aleksandar Markovic; qemu-devel@nongnu.org; peter.maydell@linaro.org; Petar Jovanovic; Miodrag Dinic; Aleksandar Rikalo
Subject: Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall

On Thu, Sep 22, 2016 at 07:05:11AM +0000, Aleksandar Markovic wrote:
> Hi, Riku,
>
> Thanks a lots for your review.
>
> I have no problem deleting "#ifdef TARGET_NR_adjtimex" in strace.c.
>
> However, I want to bring to your attention the case of future target Linux platforms seizing supporting adjtimex(). Let's say this reflects in such a way that TARGET_NR_adjtimex is not defined for such platform. Then we will have a compiler error that print_adjtimex() is unused. With "ifdef", we wouldn't.
>

To add a new plaform to qemu, changes to the code are needed anyways, so
adding an ifdef then isn't a problem. The #ifdef TARGET_NR_ guards are
useful for 1) legacy syscalls that new platforms don't support, or 2) new
syscalls that old platforms don't support (yet). adjtimex may be deprecated
on day, but even the new platforms (aarch64, ppc64le) have opted to support
it.

> Thanks,
> Aleksandar
>
> ________________________________________
> From: Riku Voipio [riku.voipio@iki.fi]
> Sent: Wednesday, September 21, 2016 9:42 PM
> To: Aleksandar Markovic
> Cc: qemu-devel@nongnu.org; peter.maydell@linaro.org; Petar Jovanovic; Miodrag Dinic; Aleksandar Rikalo; Aleksandar Markovic
> Subject: Re: [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall
>
> On Wed, Sep 14, 2016 at 10:19:54PM +0200, Aleksandar Markovic wrote:
> > From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> >
> > This patch implements Qemu user mode adjtimex() syscall support.
> >
> > Syscall adjtimex() reads and optionally sets parameters for a clock
> > adjustment algorithm used in network synchonization or similar scenarios.
> >
> > The implementation is based on invocation of host's adjtimex(), and
> > its key part is in the correspondent case segment of the main switch
> > statement of the function do_syscall(), in file linux-user/syscalls.c.
> > Also, support for related structure "timex" is added to the file
> > linux-user/syscall_defs.h, based on its definition in Linux kernel. All
> > necessary conversions of the data structures from target to host and from
> > host to target are covered. Two new functions, target_to_host_timex() and
> > host_to_target_timex(), are provided for the purpose of such conversions.
> > Moreover, the relevant support for "-strace" Qemu option is included in
> > files linux-user/strace.c and linux-user/strace.list.
> >
> > This patch also fixes failures of LTP tests adjtimex01 and adjtimex02, if
> > executed in Qemu user mode.
> >
> > Signed-off-by: Aleksandar Rikalo <aleksandar.rikalo@imgtec.com>
> > Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> > ---
> >  linux-user/strace.c       | 12 +++++++
> >  linux-user/strace.list    |  2 +-
> >  linux-user/syscall.c      | 90 ++++++++++++++++++++++++++++++++++++++++++++++-
> >  linux-user/syscall_defs.h | 28 +++++++++++++++
> >  4 files changed, 130 insertions(+), 2 deletions(-)
> >
> > diff --git a/linux-user/strace.c b/linux-user/strace.c
> > index cc10dc4..7ddcaf8 100644
> > --- a/linux-user/strace.c
> > +++ b/linux-user/strace.c
> > @@ -919,6 +919,18 @@ print_access(const struct syscallname *name,
> >  }
> >  #endif
> >
> > +#ifdef TARGET_NR_adjtimex
>
> The ifdef isn't needed, all linux platorms support adjtimex.
>
> > +static void
> > +print_adjtimex(const struct syscallname *name,
> > +    abi_long arg0, abi_long arg1, abi_long arg2,
> > +    abi_long arg3, abi_long arg4, abi_long arg5)
> > +{
> > +    print_syscall_prologue(name);
> > +    print_pointer(arg0, 1);
> > +    print_syscall_epilogue(name);
> > +}
> > +#endif
> > +
> >  #ifdef TARGET_NR_brk
> >  static void
> >  print_brk(const struct syscallname *name,
> > diff --git a/linux-user/strace.list b/linux-user/strace.list
> > index aa967a2..9a665a8 100644
> > --- a/linux-user/strace.list
> > +++ b/linux-user/strace.list
> > @@ -16,7 +16,7 @@
> >  { TARGET_NR_add_key, "add_key" , NULL, NULL, NULL },
> >  #endif
> >  #ifdef TARGET_NR_adjtimex
> > -{ TARGET_NR_adjtimex, "adjtimex" , NULL, NULL, NULL },
> > +{ TARGET_NR_adjtimex, "adjtimex" , NULL, print_adjtimex, NULL },
> >  #endif
> >  #ifdef TARGET_NR_afs_syscall
> >  { TARGET_NR_afs_syscall, "afs_syscall" , NULL, NULL, NULL },
> > diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> > index ca06943..5643840 100644
> > --- a/linux-user/syscall.c
> > +++ b/linux-user/syscall.c
> > @@ -35,6 +35,7 @@
> >  #include <sys/swap.h>
> >  #include <linux/capability.h>
> >  #include <sched.h>
> > +#include <sys/timex.h>
> >  #ifdef __ia64__
> >  int __clone2(int (*fn)(void *), void *child_stack_base,
> >               size_t stack_size, int flags, void *arg, ...);
> > @@ -6578,6 +6579,78 @@ static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
> >  }
> >  #endif
> >
> > +#ifdef TARGET_NR_adjtimex
> > +static inline abi_long target_to_host_timex(struct timex *host_buf,
> > +                                            abi_long target_addr)
> > +{
> > +    struct target_timex *target_buf;
> > +
> > +    if (!lock_user_struct(VERIFY_READ, target_buf, target_addr, 1)) {
> > +        return -TARGET_EFAULT;
> > +    }
> > +
> > +    host_buf->modes = tswap32(target_buf->modes);
> > +    host_buf->offset = tswapal(target_buf->offset);
> > +    host_buf->freq = tswapal(target_buf->freq);
> > +    host_buf->maxerror = tswapal(target_buf->maxerror);
> > +    host_buf->esterror = tswapal(target_buf->esterror);
> > +    host_buf->status = tswap32(target_buf->status);
> > +    host_buf->constant = tswapal(target_buf->constant);
> > +    host_buf->precision = tswapal(target_buf->precision);
> > +    host_buf->tolerance = tswapal(target_buf->tolerance);
> > +    host_buf->time.tv_sec = tswapal(target_buf->time.tv_sec);
> > +    host_buf->time.tv_usec = tswapal(target_buf->time.tv_usec);
> > +    host_buf->tick = tswapal(target_buf->tick);
> > +    host_buf->ppsfreq = tswapal(target_buf->ppsfreq);
> > +    host_buf->jitter = tswapal(target_buf->jitter);
> > +    host_buf->shift = tswap32(target_buf->shift);
> > +    host_buf->stabil = tswapal(target_buf->stabil);
> > +    host_buf->jitcnt = tswapal(target_buf->jitcnt);
> > +    host_buf->calcnt = tswapal(target_buf->calcnt);
> > +    host_buf->errcnt = tswapal(target_buf->errcnt);
> > +    host_buf->stbcnt = tswapal(target_buf->stbcnt);
> > +    host_buf->tai = tswap32(target_buf->tai);
> > +
> > +    unlock_user_struct(target_buf, target_addr, 0);
> > +    return 0;
> > +}
> > +
> > +static inline abi_long host_to_target_timex(abi_long target_addr,
> > +                                            struct timex *host_buf)
> > +{
> > +    struct target_timex *target_buf;
> > +
> > +    if (!lock_user_struct(VERIFY_WRITE, target_buf, target_addr, 0)) {
> > +        return -TARGET_EFAULT;
> > +    }
> > +
> > +    target_buf->modes = tswap32(host_buf->modes);
> > +    target_buf->offset = tswapal(host_buf->offset);
> > +    target_buf->freq = tswapal(host_buf->freq);
> > +    target_buf->maxerror = tswapal(host_buf->maxerror);
> > +    target_buf->esterror = tswapal(host_buf->esterror);
> > +    target_buf->status = tswap32(host_buf->status);
> > +    target_buf->constant = tswapal(host_buf->constant);
> > +    target_buf->precision = tswapal(host_buf->precision);
> > +    target_buf->tolerance = tswapal(host_buf->tolerance);
> > +    target_buf->time.tv_sec = tswapal(host_buf->time.tv_sec);
> > +    target_buf->time.tv_usec = tswapal(host_buf->time.tv_usec);
> > +    target_buf->tick = tswapal(host_buf->tick);
> > +    target_buf->ppsfreq = tswapal(host_buf->ppsfreq);
> > +    target_buf->jitter = tswapal(host_buf->jitter);
> > +    target_buf->shift = tswap32(host_buf->shift);
> > +    target_buf->stabil = tswapal(host_buf->stabil);
> > +    target_buf->jitcnt = tswapal(host_buf->jitcnt);
> > +    target_buf->calcnt = tswapal(host_buf->calcnt);
> > +    target_buf->errcnt = tswapal(host_buf->errcnt);
> > +    target_buf->stbcnt = tswapal(host_buf->stbcnt);
> > +    target_buf->tai = tswap32(host_buf->tai);
> > +
> > +    unlock_user_struct(target_buf, target_addr, 1);
> > +    return 0;
> > +}
> > +#endif
> > +
> >  static inline abi_long target_to_host_timespec(struct timespec *host_ts,
> >                                                 abi_ulong target_addr)
> >  {
> > @@ -9419,8 +9492,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> >          break;
> >  #endif
> >  #endif
> > +#ifdef TARGET_NR_adjtimex
> >      case TARGET_NR_adjtimex:
> > -        goto unimplemented;
> > +        {
> > +            struct timex host_buf;
> > +
> > +            if (target_to_host_timex(&host_buf, arg1) != 0) {
> > +                goto efault;
> > +            }
> > +            ret = get_errno(adjtimex(&host_buf));
> > +            if (!is_error(ret) && arg1) {
> > +                if (host_to_target_timex(arg1, &host_buf) != 0) {
> > +                    goto efault;
> > +                }
> > +            }
> > +        }
> > +        break;
> > +#endif
> >  #ifdef TARGET_NR_create_module
> >      case TARGET_NR_create_module:
> >  #endif
> > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> > index 7835654..afd9191 100644
> > --- a/linux-user/syscall_defs.h
> > +++ b/linux-user/syscall_defs.h
> > @@ -207,6 +207,34 @@ struct target_itimerspec {
> >      struct target_timespec it_value;
> >  };
> >
> > +struct target_timex {
> > +    unsigned int modes;          /* Mode selector */
> > +    abi_long offset;             /* Time offset */
> > +    abi_long freq;               /* Frequency offset */
> > +    abi_long maxerror;           /* Maximum error (microseconds) */
> > +    abi_long esterror;           /* Estimated error (microseconds) */
> > +    int status;                  /* Clock command/status */
> > +    abi_long constant;           /* PLL (phase-locked loop) time constant */
> > +    abi_long precision;          /* Clock precision (microseconds, ro) */
> > +    abi_long tolerance;          /* Clock freq. tolerance (ppm, ro) */
> > +    struct target_timeval time;  /* Current time */
> > +    abi_long tick;               /* Microseconds between clock ticks */
> > +    abi_long ppsfreq;            /* PPS (pulse per second) frequency */
> > +    abi_long jitter;             /* PPS jitter (ro); nanoseconds */
> > +    int shift;                   /* PPS interval duration (seconds) */
> > +    abi_long stabil;             /* PPS stability */
> > +    abi_long jitcnt;             /* PPS jitter limit exceeded (ro) */
> > +    abi_long calcnt;             /* PPS calibration intervals */
> > +    abi_long errcnt;             /* PPS calibration errors */
> > +    abi_long stbcnt;             /* PPS stability limit exceeded */
> > +    int tai;                     /* TAI offset */
> > +
> > +    /* Further padding bytes to allow for future expansion */
> > +    int:32; int:32; int:32; int:32;
> > +    int:32; int:32; int:32; int:32;
> > +    int:32; int:32; int:32;
> > +};
> > +
> >  typedef abi_long target_clock_t;
> >
> >  #define TARGET_HZ 100
> > --
> > 2.9.3
> >
> >

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

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

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-14 20:19 [Qemu-devel] [PATCH v5 0/8] linux user: Fix assorted Qemu user mode issues Aleksandar Markovic
2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 1/8] linux-user: Add support for adjtimex() syscall Aleksandar Markovic
2016-09-17 18:40   ` Laurent Vivier
2016-09-17 22:38     ` Laurent Vivier
2016-09-22  4:42   ` Riku Voipio
2016-09-22  7:05     ` Aleksandar Markovic
2016-09-22  8:12       ` Riku Voipio
2016-09-22 12:28         ` Aleksandar Markovic
2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 2/8] linux-user: Add support for clock_adjtime() syscall Aleksandar Markovic
2016-09-17 22:41   ` Laurent Vivier
2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 3/8] linux-user: Add support for sysfs() syscall Aleksandar Markovic
2016-09-17 23:28   ` Laurent Vivier
2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 4/8] linux-user: Add support for ustat() syscall Aleksandar Markovic
2016-09-17 23:39   ` Laurent Vivier
2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 5/8] linux-user: Fix msgrcv() and msgsnd() syscalls support Aleksandar Markovic
2016-09-17 23:43   ` Laurent Vivier
2016-09-19 19:05     ` Aleksandar Markovic
2016-09-14 20:19 ` [Qemu-devel] [PATCH v5 6/8] linux-user: Fix socketcall() syscall support Aleksandar Markovic
2016-09-18  0:02   ` Laurent Vivier
2016-09-14 20:20 ` [Qemu-devel] [PATCH v5 7/8] linux-user: Fix syslog() " Aleksandar Markovic
2016-09-18  0:38   ` Laurent Vivier
2016-09-14 20:20 ` [Qemu-devel] [PATCH v5 8/8] linux-user: Remove a duplicate item from strace.list Aleksandar Markovic
2016-09-18  0:13   ` Laurent Vivier

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.