All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes
@ 2019-05-19 20:19 Richard Henderson
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 01/13] util/path: Do not cache all filenames at startup Richard Henderson
                   ` (13 more replies)
  0 siblings, 14 replies; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This is an omnibus patchset of:

  v2: util/path: Do not cache all filenames at startup
  https://lists.gnu.org/archive/html/qemu-devel/2019-04/msg04149.html

  v1: linux-user: Fix shmat emulation by honoring host SHMLBA
  https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg03430.html

And a v3 update of

  v2: linux-user sparc fixes
  https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg02273.html


r~


Richard Henderson (13):
  util/path: Do not cache all filenames at startup
  linux-user: Rename cpu_clone_regs to cpu_clone_regs_child
  linux-user: Introduce cpu_clone_regs_parent
  linux-user/alpha: Set r20 secondary return value
  target/sparc: Define an enumeration for accessing env->regwptr
  linux-user/sparc: Use WREG constants in sparc/target_cpu.h
  linux-user/sparc: Use WREG constants in sparc/signal.c
  linux-user/sparc: Fix cpu_clone_regs
  linux-user/sparc: Flush register windows before clone/fork/vfork
  scripts/qemu-binfmt-conf: Update for sparc64
  tests/tcg/multiarch/linux-test: Fix error check for shmat
  linux-user: Fix shmat emulation by honoring host SHMLBA
  linux-user: Align mmap_find_vma to host page size

 linux-user/aarch64/target_cpu.h    |   6 +-
 linux-user/alpha/target_cpu.h      |   8 +-
 linux-user/arm/target_cpu.h        |   6 +-
 linux-user/cris/target_cpu.h       |   6 +-
 linux-user/hppa/target_cpu.h       |   6 +-
 linux-user/i386/target_cpu.h       |   6 +-
 linux-user/m68k/target_cpu.h       |   6 +-
 linux-user/microblaze/target_cpu.h |   6 +-
 linux-user/mips/target_cpu.h       |   6 +-
 linux-user/nios2/target_cpu.h      |   6 +-
 linux-user/openrisc/target_cpu.h   |   7 +-
 linux-user/ppc/target_cpu.h        |   6 +-
 linux-user/qemu.h                  |   2 +-
 linux-user/riscv/target_cpu.h      |   6 +-
 linux-user/s390x/target_cpu.h      |   6 +-
 linux-user/sh4/target_cpu.h        |   6 +-
 linux-user/sparc/target_cpu.h      |  45 ++++---
 linux-user/tilegx/target_cpu.h     |   6 +-
 linux-user/xtensa/target_cpu.h     |   7 +-
 target/sparc/cpu.h                 |  33 +++++
 linux-user/elfload.c               |  17 ++-
 linux-user/mmap.c                  |  76 ++++++-----
 linux-user/sparc/cpu_loop.c        |  12 ++
 linux-user/sparc/signal.c          |  96 +++++---------
 linux-user/syscall.c               |   9 +-
 tests/tcg/multiarch/linux-test.c   |   3 +-
 util/path.c                        | 201 +++++++----------------------
 scripts/qemu-binfmt-conf.sh        |   8 +-
 28 files changed, 309 insertions(+), 299 deletions(-)

-- 
2.17.1



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

* [Qemu-devel] [PATCH 01/13] util/path: Do not cache all filenames at startup
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-06-13 13:40   ` Laurent Vivier
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 02/13] linux-user: Rename cpu_clone_regs to cpu_clone_regs_child Richard Henderson
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

If one uses -L $PATH to point to a full chroot, the startup time
is significant.  In addition, the existing probing algorithm fails
to handle symlink loops.

Instead, probe individual paths on demand.  Cache both positive
and negative results within $PATH, so that any one filename is
probed only once.

Use glib filename functions for clarity.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 util/path.c | 201 ++++++++++++----------------------------------------
 1 file changed, 47 insertions(+), 154 deletions(-)

diff --git a/util/path.c b/util/path.c
index 7f9fc272fb..8e174eb436 100644
--- a/util/path.c
+++ b/util/path.c
@@ -8,170 +8,63 @@
 #include <dirent.h>
 #include "qemu/cutils.h"
 #include "qemu/path.h"
+#include "qemu/thread.h"
 
-struct pathelem
-{
-    /* Name of this, eg. lib */
-    char *name;
-    /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
-    char *pathname;
-    struct pathelem *parent;
-    /* Children */
-    unsigned int num_entries;
-    struct pathelem *entries[0];
-};
-
-static struct pathelem *base;
-
-/* First N chars of S1 match S2, and S2 is N chars long. */
-static int strneq(const char *s1, unsigned int n, const char *s2)
-{
-    unsigned int i;
-
-    for (i = 0; i < n; i++)
-        if (s1[i] != s2[i])
-            return 0;
-    return s2[i] == 0;
-}
-
-static struct pathelem *add_entry(struct pathelem *root, const char *name,
-                                  unsigned type);
-
-static struct pathelem *new_entry(const char *root,
-                                  struct pathelem *parent,
-                                  const char *name)
-{
-    struct pathelem *new = g_malloc(sizeof(*new));
-    new->name = g_strdup(name);
-    new->pathname = g_strdup_printf("%s/%s", root, name);
-    new->num_entries = 0;
-    return new;
-}
-
-#define streq(a,b) (strcmp((a), (b)) == 0)
-
-/* Not all systems provide this feature */
-#if defined(DT_DIR) && defined(DT_UNKNOWN) && defined(DT_LNK)
-# define dirent_type(dirent) ((dirent)->d_type)
-# define is_dir_maybe(type) \
-    ((type) == DT_DIR || (type) == DT_UNKNOWN || (type) == DT_LNK)
-#else
-# define dirent_type(dirent) (1)
-# define is_dir_maybe(type)  (type)
-#endif
-
-static struct pathelem *add_dir_maybe(struct pathelem *path)
-{
-    DIR *dir;
-
-    if ((dir = opendir(path->pathname)) != NULL) {
-        struct dirent *dirent;
-
-        while ((dirent = readdir(dir)) != NULL) {
-            if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
-                path = add_entry(path, dirent->d_name, dirent_type(dirent));
-            }
-        }
-        closedir(dir);
-    }
-    return path;
-}
-
-static struct pathelem *add_entry(struct pathelem *root, const char *name,
-                                  unsigned type)
-{
-    struct pathelem **e;
-
-    root->num_entries++;
-
-    root = g_realloc(root, sizeof(*root)
-                   + sizeof(root->entries[0])*root->num_entries);
-    e = &root->entries[root->num_entries-1];
-
-    *e = new_entry(root->pathname, root, name);
-    if (is_dir_maybe(type)) {
-        *e = add_dir_maybe(*e);
-    }
-
-    return root;
-}
-
-/* This needs to be done after tree is stabilized (ie. no more reallocs!). */
-static void set_parents(struct pathelem *child, struct pathelem *parent)
-{
-    unsigned int i;
-
-    child->parent = parent;
-    for (i = 0; i < child->num_entries; i++)
-        set_parents(child->entries[i], child);
-}
-
-/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
-static const char *
-follow_path(const struct pathelem *cursor, const char *name)
-{
-    unsigned int i, namelen;
-
-    name += strspn(name, "/");
-    namelen = strcspn(name, "/");
-
-    if (namelen == 0)
-        return cursor->pathname;
-
-    if (strneq(name, namelen, ".."))
-        return follow_path(cursor->parent, name + namelen);
-
-    if (strneq(name, namelen, "."))
-        return follow_path(cursor, name + namelen);
-
-    for (i = 0; i < cursor->num_entries; i++)
-        if (strneq(name, namelen, cursor->entries[i]->name))
-            return follow_path(cursor->entries[i], name + namelen);
-
-    /* Not found */
-    return NULL;
-}
+static const char *base;
+static GHashTable *hash;
+static QemuMutex lock;
 
 void init_paths(const char *prefix)
 {
-    char pref_buf[PATH_MAX];
-
-    if (prefix[0] == '\0' ||
-        !strcmp(prefix, "/"))
+    if (prefix[0] == '\0' || !strcmp(prefix, "/")) {
         return;
-
-    if (prefix[0] != '/') {
-        char *cwd = getcwd(NULL, 0);
-        size_t pref_buf_len = sizeof(pref_buf);
-
-        if (!cwd)
-            abort();
-        pstrcpy(pref_buf, sizeof(pref_buf), cwd);
-        pstrcat(pref_buf, pref_buf_len, "/");
-        pstrcat(pref_buf, pref_buf_len, prefix);
-        free(cwd);
-    } else
-        pstrcpy(pref_buf, sizeof(pref_buf), prefix + 1);
-
-    base = new_entry("", NULL, pref_buf);
-    base = add_dir_maybe(base);
-    if (base->num_entries == 0) {
-        g_free(base->pathname);
-        g_free(base->name);
-        g_free(base);
-        base = NULL;
-    } else {
-        set_parents(base, base);
     }
+
+    if (prefix[0] == '/') {
+        base = g_strdup(prefix);
+    } else {
+        char *cwd = g_get_current_dir();
+        base = g_build_filename(cwd, prefix, NULL);
+        g_free(cwd);
+    }
+
+    hash = g_hash_table_new(g_str_hash, g_str_equal);
+    qemu_mutex_init(&lock);
 }
 
 /* Look for path in emulation dir, otherwise return name. */
 const char *path(const char *name)
 {
-    /* Only do absolute paths: quick and dirty, but should mostly be OK.
-       Could do relative by tracking cwd. */
-    if (!base || !name || name[0] != '/')
-        return name;
+    gpointer key, value;
+    const char *ret;
 
-    return follow_path(base, name) ?: name;
+    /* Only do absolute paths: quick and dirty, but should mostly be OK.  */
+    if (!base || !name || name[0] != '/') {
+        return name;
+    }
+
+    qemu_mutex_lock(&lock);
+
+    /* Have we looked up this file before?  */
+    if (g_hash_table_lookup_extended(hash, name, &key, &value)) {
+        ret = value ? value : name;
+    } else {
+        char *save = g_strdup(name);
+        char *full = g_build_filename(base, name, NULL);
+
+        /* Look for the path; record the result, pass or fail.  */
+        if (access(full, F_OK) == 0) {
+            /* Exists.  */
+            g_hash_table_insert(hash, save, full);
+            ret = full;
+        } else {
+            /* Does not exist.  */
+            g_free(full);
+            g_hash_table_insert(hash, save, NULL);
+            ret = name;
+        }
+    }
+
+    qemu_mutex_unlock(&lock);
+    return ret;
 }
-- 
2.17.1



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

* [Qemu-devel] [PATCH 02/13] linux-user: Rename cpu_clone_regs to cpu_clone_regs_child
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 01/13] util/path: Do not cache all filenames at startup Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-06-13 16:25   ` Laurent Vivier
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 03/13] linux-user: Introduce cpu_clone_regs_parent Richard Henderson
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

We will need a target-specific hook for adjusting registers
in the parent during clone.  To avoid confusion, rename the
one we have to make it clear it affects the child.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/aarch64/target_cpu.h    | 2 +-
 linux-user/alpha/target_cpu.h      | 2 +-
 linux-user/arm/target_cpu.h        | 2 +-
 linux-user/cris/target_cpu.h       | 2 +-
 linux-user/hppa/target_cpu.h       | 2 +-
 linux-user/i386/target_cpu.h       | 2 +-
 linux-user/m68k/target_cpu.h       | 2 +-
 linux-user/microblaze/target_cpu.h | 2 +-
 linux-user/mips/target_cpu.h       | 2 +-
 linux-user/nios2/target_cpu.h      | 2 +-
 linux-user/openrisc/target_cpu.h   | 3 ++-
 linux-user/ppc/target_cpu.h        | 2 +-
 linux-user/riscv/target_cpu.h      | 2 +-
 linux-user/s390x/target_cpu.h      | 2 +-
 linux-user/sh4/target_cpu.h        | 2 +-
 linux-user/sparc/target_cpu.h      | 2 +-
 linux-user/tilegx/target_cpu.h     | 2 +-
 linux-user/xtensa/target_cpu.h     | 3 ++-
 linux-user/syscall.c               | 4 ++--
 19 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
index a021c95fa4..abde35b104 100644
--- a/linux-user/aarch64/target_cpu.h
+++ b/linux-user/aarch64/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef AARCH64_TARGET_CPU_H
 #define AARCH64_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUARMState *env, target_ulong newsp)
 {
     if (newsp) {
         env->xregs[31] = newsp;
diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h
index ac4d255ae7..dc02f2234c 100644
--- a/linux-user/alpha/target_cpu.h
+++ b/linux-user/alpha/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef ALPHA_TARGET_CPU_H
 #define ALPHA_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUAlphaState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUAlphaState *env, target_ulong newsp)
 {
     if (newsp) {
         env->ir[IR_SP] = newsp;
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
index 8a3764919a..d35c997287 100644
--- a/linux-user/arm/target_cpu.h
+++ b/linux-user/arm/target_cpu.h
@@ -23,7 +23,7 @@
    See validate_guest_space in linux-user/elfload.c.  */
 #define MAX_RESERVED_VA  0xffff0000ul
 
-static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUARMState *env, target_ulong newsp)
 {
     if (newsp) {
         env->regs[13] = newsp;
diff --git a/linux-user/cris/target_cpu.h b/linux-user/cris/target_cpu.h
index 2309343979..9c847caaef 100644
--- a/linux-user/cris/target_cpu.h
+++ b/linux-user/cris/target_cpu.h
@@ -20,7 +20,7 @@
 #ifndef CRIS_TARGET_CPU_H
 #define CRIS_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUCRISState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUCRISState *env, target_ulong newsp)
 {
     if (newsp) {
         env->regs[14] = newsp;
diff --git a/linux-user/hppa/target_cpu.h b/linux-user/hppa/target_cpu.h
index 1c539bdbd6..b98e5a1cfe 100644
--- a/linux-user/hppa/target_cpu.h
+++ b/linux-user/hppa/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef HPPA_TARGET_CPU_H
 #define HPPA_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUHPPAState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUHPPAState *env, target_ulong newsp)
 {
     if (newsp) {
         env->gr[30] = newsp;
diff --git a/linux-user/i386/target_cpu.h b/linux-user/i386/target_cpu.h
index ece04d0966..e1c9e03490 100644
--- a/linux-user/i386/target_cpu.h
+++ b/linux-user/i386/target_cpu.h
@@ -20,7 +20,7 @@
 #ifndef I386_TARGET_CPU_H
 #define I386_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUX86State *env, target_ulong newsp)
 {
     if (newsp) {
         env->regs[R_ESP] = newsp;
diff --git a/linux-user/m68k/target_cpu.h b/linux-user/m68k/target_cpu.h
index 7a26f3c3fc..7637a98cab 100644
--- a/linux-user/m68k/target_cpu.h
+++ b/linux-user/m68k/target_cpu.h
@@ -21,7 +21,7 @@
 #ifndef M68K_TARGET_CPU_H
 #define M68K_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUM68KState *env, target_ulong newsp)
 {
     if (newsp) {
         env->aregs[7] = newsp;
diff --git a/linux-user/microblaze/target_cpu.h b/linux-user/microblaze/target_cpu.h
index 73e139938c..526b80d54d 100644
--- a/linux-user/microblaze/target_cpu.h
+++ b/linux-user/microblaze/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef MICROBLAZE_TARGET_CPU_H
 #define MICROBLAZE_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUMBState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUMBState *env, target_ulong newsp)
 {
     if (newsp) {
         env->regs[R_SP] = newsp;
diff --git a/linux-user/mips/target_cpu.h b/linux-user/mips/target_cpu.h
index 02cf5eeff7..c42660b047 100644
--- a/linux-user/mips/target_cpu.h
+++ b/linux-user/mips/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef MIPS_TARGET_CPU_H
 #define MIPS_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUMIPSState *env, target_ulong newsp)
 {
     if (newsp) {
         env->active_tc.gpr[29] = newsp;
diff --git a/linux-user/nios2/target_cpu.h b/linux-user/nios2/target_cpu.h
index 5596c05c9c..bec2ea79c4 100644
--- a/linux-user/nios2/target_cpu.h
+++ b/linux-user/nios2/target_cpu.h
@@ -20,7 +20,7 @@
 #ifndef NIOS2_TARGET_CPU_H
 #define NIOS2_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUNios2State *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUNios2State *env, target_ulong newsp)
 {
     if (newsp) {
         env->regs[R_SP] = newsp;
diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h
index 32ff135089..d163ba2e26 100644
--- a/linux-user/openrisc/target_cpu.h
+++ b/linux-user/openrisc/target_cpu.h
@@ -20,7 +20,8 @@
 #ifndef OPENRISC_TARGET_CPU_H
 #define OPENRISC_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUOpenRISCState *env,
+                                        target_ulong newsp)
 {
     if (newsp) {
         cpu_set_gpr(env, 1, newsp);
diff --git a/linux-user/ppc/target_cpu.h b/linux-user/ppc/target_cpu.h
index c4641834e7..34decf3876 100644
--- a/linux-user/ppc/target_cpu.h
+++ b/linux-user/ppc/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef PPC_TARGET_CPU_H
 #define PPC_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUPPCState *env, target_ulong newsp)
 {
     if (newsp) {
         env->gpr[1] = newsp;
diff --git a/linux-user/riscv/target_cpu.h b/linux-user/riscv/target_cpu.h
index 90f9a4171e..d92153851c 100644
--- a/linux-user/riscv/target_cpu.h
+++ b/linux-user/riscv/target_cpu.h
@@ -1,7 +1,7 @@
 #ifndef RISCV_TARGET_CPU_H
 #define RISCV_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPURISCVState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPURISCVState *env, target_ulong newsp)
 {
     if (newsp) {
         env->gpr[xSP] = newsp;
diff --git a/linux-user/s390x/target_cpu.h b/linux-user/s390x/target_cpu.h
index aa181ceaee..e0baa98e75 100644
--- a/linux-user/s390x/target_cpu.h
+++ b/linux-user/s390x/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef S390X_TARGET_CPU_H
 #define S390X_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUS390XState *env, target_ulong newsp)
 {
     if (newsp) {
         env->regs[15] = newsp;
diff --git a/linux-user/sh4/target_cpu.h b/linux-user/sh4/target_cpu.h
index b0be9a2c1b..854955aa5a 100644
--- a/linux-user/sh4/target_cpu.h
+++ b/linux-user/sh4/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef SH4_TARGET_CPU_H
 #define SH4_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUSH4State *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUSH4State *env, target_ulong newsp)
 {
     if (newsp) {
         env->gregs[15] = newsp;
diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
index 1ffc0ae9f2..8511fc3f6f 100644
--- a/linux-user/sparc/target_cpu.h
+++ b/linux-user/sparc/target_cpu.h
@@ -20,7 +20,7 @@
 #ifndef SPARC_TARGET_CPU_H
 #define SPARC_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp)
 {
     if (newsp) {
         env->regwptr[22] = newsp;
diff --git a/linux-user/tilegx/target_cpu.h b/linux-user/tilegx/target_cpu.h
index d1aa5824f2..dfca8d9598 100644
--- a/linux-user/tilegx/target_cpu.h
+++ b/linux-user/tilegx/target_cpu.h
@@ -19,7 +19,7 @@
 #ifndef TILEGX_TARGET_CPU_H
 #define TILEGX_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUTLGState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUTLGState *env, target_ulong newsp)
 {
     if (newsp) {
         env->regs[TILEGX_R_SP] = newsp;
diff --git a/linux-user/xtensa/target_cpu.h b/linux-user/xtensa/target_cpu.h
index e31efe3ea0..f436b160c4 100644
--- a/linux-user/xtensa/target_cpu.h
+++ b/linux-user/xtensa/target_cpu.h
@@ -4,7 +4,8 @@
 #ifndef XTENSA_TARGET_CPU_H
 #define XTENSA_TARGET_CPU_H
 
-static inline void cpu_clone_regs(CPUXtensaState *env, target_ulong newsp)
+static inline void cpu_clone_regs_child(CPUXtensaState *env,
+                                        target_ulong newsp)
 {
     if (newsp) {
         env->regs[1] = newsp;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f5ff6f5dc8..b9127a9601 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5534,7 +5534,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         /* we create a new CPU instance. */
         new_env = cpu_copy(env);
         /* Init regs that differ from the parent.  */
-        cpu_clone_regs(new_env, newsp);
+        cpu_clone_regs_child(new_env, newsp);
         new_cpu = ENV_GET_CPU(new_env);
         new_cpu->opaque = ts;
         ts->bprm = parent_ts->bprm;
@@ -5612,7 +5612,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         ret = fork();
         if (ret == 0) {
             /* Child Process.  */
-            cpu_clone_regs(env, newsp);
+            cpu_clone_regs_child(env, newsp);
             fork_end(1);
             /* There is a race condition here.  The parent process could
                theoretically read the TID in the child process before the child
-- 
2.17.1



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

* [Qemu-devel] [PATCH 03/13] linux-user: Introduce cpu_clone_regs_parent
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 01/13] util/path: Do not cache all filenames at startup Richard Henderson
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 02/13] linux-user: Rename cpu_clone_regs to cpu_clone_regs_child Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-06-13 16:26   ` Laurent Vivier
  2019-06-13 19:10   ` Aleksandar Markovic
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 04/13] linux-user/alpha: Set r20 secondary return value Richard Henderson
                   ` (10 subsequent siblings)
  13 siblings, 2 replies; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Add an empty inline function for each target, and invoke it
from the proper places.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/aarch64/target_cpu.h    | 4 ++++
 linux-user/alpha/target_cpu.h      | 4 ++++
 linux-user/arm/target_cpu.h        | 4 ++++
 linux-user/cris/target_cpu.h       | 4 ++++
 linux-user/hppa/target_cpu.h       | 4 ++++
 linux-user/i386/target_cpu.h       | 4 ++++
 linux-user/m68k/target_cpu.h       | 4 ++++
 linux-user/microblaze/target_cpu.h | 4 ++++
 linux-user/mips/target_cpu.h       | 4 ++++
 linux-user/nios2/target_cpu.h      | 4 ++++
 linux-user/openrisc/target_cpu.h   | 4 ++++
 linux-user/ppc/target_cpu.h        | 4 ++++
 linux-user/riscv/target_cpu.h      | 4 ++++
 linux-user/s390x/target_cpu.h      | 4 ++++
 linux-user/sh4/target_cpu.h        | 4 ++++
 linux-user/sparc/target_cpu.h      | 4 ++++
 linux-user/tilegx/target_cpu.h     | 4 ++++
 linux-user/xtensa/target_cpu.h     | 4 ++++
 linux-user/syscall.c               | 2 ++
 19 files changed, 74 insertions(+)

diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
index abde35b104..0182bfca07 100644
--- a/linux-user/aarch64/target_cpu.h
+++ b/linux-user/aarch64/target_cpu.h
@@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUARMState *env, target_ulong newsp)
     env->xregs[0] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUARMState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
 {
     /* Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h
index dc02f2234c..140a459f73 100644
--- a/linux-user/alpha/target_cpu.h
+++ b/linux-user/alpha/target_cpu.h
@@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUAlphaState *env, target_ulong newsp)
     env->ir[IR_A3] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUAlphaState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
 {
     env->unique = newtls;
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
index d35c997287..3e66d5b106 100644
--- a/linux-user/arm/target_cpu.h
+++ b/linux-user/arm/target_cpu.h
@@ -31,6 +31,10 @@ static inline void cpu_clone_regs_child(CPUARMState *env, target_ulong newsp)
     env->regs[0] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUARMState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
 {
     if (access_secure_reg(env)) {
diff --git a/linux-user/cris/target_cpu.h b/linux-user/cris/target_cpu.h
index 9c847caaef..4da074b4fd 100644
--- a/linux-user/cris/target_cpu.h
+++ b/linux-user/cris/target_cpu.h
@@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUCRISState *env, target_ulong newsp)
     env->regs[10] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUCRISState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUCRISState *env, target_ulong newtls)
 {
     env->pregs[PR_PID] = (env->pregs[PR_PID] & 0xff) | newtls;
diff --git a/linux-user/hppa/target_cpu.h b/linux-user/hppa/target_cpu.h
index b98e5a1cfe..6b323297af 100644
--- a/linux-user/hppa/target_cpu.h
+++ b/linux-user/hppa/target_cpu.h
@@ -31,6 +31,10 @@ static inline void cpu_clone_regs_child(CPUHPPAState *env, target_ulong newsp)
     env->iaoq_b = env->gr[31] + 4;
 }
 
+static inline void cpu_clone_regs_parent(CPUHPPAState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUHPPAState *env, target_ulong newtls)
 {
     env->cr[27] = newtls;
diff --git a/linux-user/i386/target_cpu.h b/linux-user/i386/target_cpu.h
index e1c9e03490..6dbb856c52 100644
--- a/linux-user/i386/target_cpu.h
+++ b/linux-user/i386/target_cpu.h
@@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUX86State *env, target_ulong newsp)
     env->regs[R_EAX] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUX86State *env)
+{
+}
+
 #if defined(TARGET_ABI32)
 abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr);
 
diff --git a/linux-user/m68k/target_cpu.h b/linux-user/m68k/target_cpu.h
index 7637a98cab..f1a53cdee5 100644
--- a/linux-user/m68k/target_cpu.h
+++ b/linux-user/m68k/target_cpu.h
@@ -29,6 +29,10 @@ static inline void cpu_clone_regs_child(CPUM68KState *env, target_ulong newsp)
     env->dregs[0] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUM68KState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUM68KState *env, target_ulong newtls)
 {
     CPUState *cs = CPU(m68k_env_get_cpu(env));
diff --git a/linux-user/microblaze/target_cpu.h b/linux-user/microblaze/target_cpu.h
index 526b80d54d..5e285e9211 100644
--- a/linux-user/microblaze/target_cpu.h
+++ b/linux-user/microblaze/target_cpu.h
@@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUMBState *env, target_ulong newsp)
     env->regs[3] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUMBState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUMBState *env, target_ulong newtls)
 {
     env->regs[21] = newtls;
diff --git a/linux-user/mips/target_cpu.h b/linux-user/mips/target_cpu.h
index c42660b047..d0e0b1bac0 100644
--- a/linux-user/mips/target_cpu.h
+++ b/linux-user/mips/target_cpu.h
@@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUMIPSState *env, target_ulong newsp)
     env->active_tc.gpr[2] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUMIPSState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls)
 {
     env->active_tc.CP0_UserLocal = newtls;
diff --git a/linux-user/nios2/target_cpu.h b/linux-user/nios2/target_cpu.h
index bec2ea79c4..01725ba004 100644
--- a/linux-user/nios2/target_cpu.h
+++ b/linux-user/nios2/target_cpu.h
@@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUNios2State *env, target_ulong newsp)
     env->regs[R_RET0] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUNios2State *env)
+{
+}
+
 static inline void cpu_set_tls(CPUNios2State *env, target_ulong newtls)
 {
     /*
diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h
index d163ba2e26..6586951c5b 100644
--- a/linux-user/openrisc/target_cpu.h
+++ b/linux-user/openrisc/target_cpu.h
@@ -29,6 +29,10 @@ static inline void cpu_clone_regs_child(CPUOpenRISCState *env,
     cpu_set_gpr(env, 11, 0);
 }
 
+static inline void cpu_clone_regs_parent(CPUOpenRISCState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls)
 {
     cpu_set_gpr(env, 10, newtls);
diff --git a/linux-user/ppc/target_cpu.h b/linux-user/ppc/target_cpu.h
index 34decf3876..00c9f5eb86 100644
--- a/linux-user/ppc/target_cpu.h
+++ b/linux-user/ppc/target_cpu.h
@@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUPPCState *env, target_ulong newsp)
     env->gpr[3] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUPPCState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUPPCState *env, target_ulong newtls)
 {
 #if defined(TARGET_PPC64)
diff --git a/linux-user/riscv/target_cpu.h b/linux-user/riscv/target_cpu.h
index d92153851c..4ef1b23b4f 100644
--- a/linux-user/riscv/target_cpu.h
+++ b/linux-user/riscv/target_cpu.h
@@ -10,6 +10,10 @@ static inline void cpu_clone_regs_child(CPURISCVState *env, target_ulong newsp)
     env->gpr[xA0] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPURISCVState *env)
+{
+}
+
 static inline void cpu_set_tls(CPURISCVState *env, target_ulong newtls)
 {
     env->gpr[xTP] = newtls;
diff --git a/linux-user/s390x/target_cpu.h b/linux-user/s390x/target_cpu.h
index e0baa98e75..18e290ece8 100644
--- a/linux-user/s390x/target_cpu.h
+++ b/linux-user/s390x/target_cpu.h
@@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUS390XState *env, target_ulong newsp)
     env->regs[2] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUS390XState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
 {
     env->aregs[0] = newtls >> 32;
diff --git a/linux-user/sh4/target_cpu.h b/linux-user/sh4/target_cpu.h
index 854955aa5a..b0e4ab23a7 100644
--- a/linux-user/sh4/target_cpu.h
+++ b/linux-user/sh4/target_cpu.h
@@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUSH4State *env, target_ulong newsp)
     env->gregs[0] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUSH4State *env)
+{
+}
+
 static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls)
 {
   env->gbr = newtls;
diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
index 8511fc3f6f..52c9d8c7db 100644
--- a/linux-user/sparc/target_cpu.h
+++ b/linux-user/sparc/target_cpu.h
@@ -36,6 +36,10 @@ static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp)
 #endif
 }
 
+static inline void cpu_clone_regs_parent(CPUSPARCState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
 {
     env->gregs[7] = newtls;
diff --git a/linux-user/tilegx/target_cpu.h b/linux-user/tilegx/target_cpu.h
index dfca8d9598..9577462821 100644
--- a/linux-user/tilegx/target_cpu.h
+++ b/linux-user/tilegx/target_cpu.h
@@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUTLGState *env, target_ulong newsp)
     env->regs[TILEGX_R_RE] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUTLGState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUTLGState *env, target_ulong newtls)
 {
     env->regs[TILEGX_R_TP] = newtls;
diff --git a/linux-user/xtensa/target_cpu.h b/linux-user/xtensa/target_cpu.h
index f436b160c4..42e66211cf 100644
--- a/linux-user/xtensa/target_cpu.h
+++ b/linux-user/xtensa/target_cpu.h
@@ -15,6 +15,10 @@ static inline void cpu_clone_regs_child(CPUXtensaState *env,
     env->regs[2] = 0;
 }
 
+static inline void cpu_clone_regs_parent(CPUXtensaState *env)
+{
+}
+
 static inline void cpu_set_tls(CPUXtensaState *env, target_ulong newtls)
 {
     env->uregs[THREADPTR] = newtls;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index b9127a9601..f960556bf8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5535,6 +5535,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         new_env = cpu_copy(env);
         /* Init regs that differ from the parent.  */
         cpu_clone_regs_child(new_env, newsp);
+        cpu_clone_regs_parent(env);
         new_cpu = ENV_GET_CPU(new_env);
         new_cpu->opaque = ts;
         ts->bprm = parent_ts->bprm;
@@ -5630,6 +5631,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
             if (flags & CLONE_CHILD_CLEARTID)
                 ts->child_tidptr = child_tidptr;
         } else {
+            cpu_clone_regs_parent(env);
             fork_end(0);
         }
     }
-- 
2.17.1



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

* [Qemu-devel] [PATCH 04/13] linux-user/alpha: Set r20 secondary return value
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (2 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 03/13] linux-user: Introduce cpu_clone_regs_parent Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-06-13 16:23   ` Laurent Vivier
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 05/13] target/sparc: Define an enumeration for accessing env->regwptr Richard Henderson
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This value is not, as far as I know, used by any linux software,
but it is set by the kernel and is part of the ABI.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/alpha/target_cpu.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h
index 140a459f73..caadb54372 100644
--- a/linux-user/alpha/target_cpu.h
+++ b/linux-user/alpha/target_cpu.h
@@ -26,10 +26,12 @@ static inline void cpu_clone_regs_child(CPUAlphaState *env, target_ulong newsp)
     }
     env->ir[IR_V0] = 0;
     env->ir[IR_A3] = 0;
+    env->ir[IR_A4] = 1;  /* OSF/1 secondary return: child */
 }
 
 static inline void cpu_clone_regs_parent(CPUAlphaState *env)
 {
+    env->ir[IR_A4] = 0;  /* OSF/1 secondary return: parent */
 }
 
 static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
-- 
2.17.1



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

* [Qemu-devel] [PATCH 05/13] target/sparc: Define an enumeration for accessing env->regwptr
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (3 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 04/13] linux-user/alpha: Set r20 secondary return value Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 06/13] linux-user/sparc: Use WREG constants in sparc/target_cpu.h Richard Henderson
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/sparc/cpu.h | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index f31e8535df..f0ac3ac086 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -31,6 +31,39 @@
 
 /*#define EXCP_INTERRUPT 0x100*/
 
+/* Windowed register indexes.  */
+enum {
+    WREG_O0,
+    WREG_O1,
+    WREG_O2,
+    WREG_O3,
+    WREG_O4,
+    WREG_O5,
+    WREG_O6,
+    WREG_O7,
+
+    WREG_L0,
+    WREG_L1,
+    WREG_L2,
+    WREG_L3,
+    WREG_L4,
+    WREG_L5,
+    WREG_L6,
+    WREG_L7,
+
+    WREG_I0,
+    WREG_I1,
+    WREG_I2,
+    WREG_I3,
+    WREG_I4,
+    WREG_I5,
+    WREG_I6,
+    WREG_I7,
+
+    WREG_SP = WREG_O6,
+    WREG_FP = WREG_I6,
+};
+
 /* trap definitions */
 #ifndef TARGET_SPARC64
 #define TT_TFAULT   0x01
-- 
2.17.1



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

* [Qemu-devel] [PATCH 06/13] linux-user/sparc: Use WREG constants in sparc/target_cpu.h
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (4 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 05/13] target/sparc: Define an enumeration for accessing env->regwptr Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 07/13] linux-user/sparc: Use WREG constants in sparc/signal.c Richard Henderson
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This fixes a naming bug wherein we used "UREG_FP" to access the
stack pointer.  OTOH, the "UREG_FP" constant was also defined
incorrectly such that it *did* reference the stack pointer.

Note that the kernel legitimately uses the name "FP", because it
utilizes the rolled stack window in processing the system call.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/sparc/target_cpu.h | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
index 52c9d8c7db..2c80db4889 100644
--- a/linux-user/sparc/target_cpu.h
+++ b/linux-user/sparc/target_cpu.h
@@ -45,15 +45,9 @@ static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
     env->gregs[7] = newtls;
 }
 
-#ifndef UREG_I6
-#define UREG_I6        6
-#endif
-#ifndef UREG_FP
-#define UREG_FP        UREG_I6
-#endif
-
 static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
 {
-    return state->regwptr[UREG_FP];
+    return state->regwptr[WREG_SP];
 }
+
 #endif
-- 
2.17.1



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

* [Qemu-devel] [PATCH 07/13] linux-user/sparc: Use WREG constants in sparc/signal.c
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (5 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 06/13] linux-user/sparc: Use WREG constants in sparc/target_cpu.h Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-06-13 21:31   ` Laurent Vivier
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 08/13] linux-user/sparc: Fix cpu_clone_regs Richard Henderson
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Remove the incorrectly defined UREG constants.

Maddeningly, in some cases we used the correct constant getting
the env register wrong, and in other cases we used the incorrect
constant getting the env register right.

In the case of getcontext/setcontext, we are aided by the fact
that the "other" constant, e.g. SPARC_MC_O0, is correct.  So we
can easily guess that the WREG_* constant on the other side
should also be O0.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/sparc/signal.c | 96 +++++++++++++--------------------------
 1 file changed, 32 insertions(+), 64 deletions(-)

diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
index ead169fbaa..243f237528 100644
--- a/linux-user/sparc/signal.c
+++ b/linux-user/sparc/signal.c
@@ -104,20 +104,6 @@ struct target_rt_signal_frame {
     qemu_siginfo_fpu_t  fpu_state;
 };
 
-#define UREG_O0        16
-#define UREG_O6        22
-#define UREG_I0        0
-#define UREG_I1        1
-#define UREG_I2        2
-#define UREG_I3        3
-#define UREG_I4        4
-#define UREG_I5        5
-#define UREG_I6        6
-#define UREG_I7        7
-#define UREG_L0        8
-#define UREG_FP        UREG_I6
-#define UREG_SP        UREG_O6
-
 static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
                                      CPUSPARCState *env,
                                      unsigned long framesize)
@@ -159,30 +145,12 @@ setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
         __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
     }
     for (i=0; i < 8; i++) {
-        __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
+        __put_user(env->regwptr[WREG_O0 + i], &si->si_regs.u_regs[i+8]);
     }
     __put_user(mask, &si->si_mask);
     return err;
 }
 
-#if 0
-static int
-setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
-                 CPUSPARCState *env, unsigned long mask)
-{
-    int err = 0;
-
-    __put_user(mask, &sc->sigc_mask);
-    __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
-    __put_user(env->pc, &sc->sigc_pc);
-    __put_user(env->npc, &sc->sigc_npc);
-    __put_user(env->psr, &sc->sigc_psr);
-    __put_user(env->gregs[1], &sc->sigc_g1);
-    __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
-
-    return err;
-}
-#endif
 #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
 
 void setup_frame(int sig, struct target_sigaction *ka,
@@ -221,20 +189,20 @@ void setup_frame(int sig, struct target_sigaction *ka,
     }
 
     for (i = 0; i < 8; i++) {
-        __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
+        __put_user(env->regwptr[i + WREG_L0], &sf->ss.locals[i]);
     }
     for (i = 0; i < 8; i++) {
-        __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
+        __put_user(env->regwptr[i + WREG_I0], &sf->ss.ins[i]);
     }
     if (err)
         goto sigsegv;
 
     /* 3. signal handler back-trampoline and parameters */
-    env->regwptr[UREG_FP] = sf_addr;
-    env->regwptr[UREG_I0] = sig;
-    env->regwptr[UREG_I1] = sf_addr +
+    env->regwptr[WREG_FP] = sf_addr;
+    env->regwptr[WREG_I0] = sig;
+    env->regwptr[WREG_I1] = sf_addr +
             offsetof(struct target_signal_frame, info);
-    env->regwptr[UREG_I2] = sf_addr +
+    env->regwptr[WREG_I2] = sf_addr +
             offsetof(struct target_signal_frame, info);
 
     /* 4. signal handler */
@@ -242,11 +210,11 @@ void setup_frame(int sig, struct target_sigaction *ka,
     env->npc = (env->pc + 4);
     /* 5. return to kernel instructions */
     if (ka->ka_restorer) {
-        env->regwptr[UREG_I7] = ka->ka_restorer;
+        env->regwptr[WREG_I7] = ka->ka_restorer;
     } else {
         uint32_t val32;
 
-        env->regwptr[UREG_I7] = sf_addr +
+        env->regwptr[WREG_I7] = sf_addr +
                 offsetof(struct target_signal_frame, insns) - 2 * 4;
 
         /* mov __NR_sigreturn, %g1 */
@@ -284,7 +252,7 @@ long do_sigreturn(CPUSPARCState *env)
     sigset_t host_set;
     int i;
 
-    sf_addr = env->regwptr[UREG_FP];
+    sf_addr = env->regwptr[WREG_SP];
     trace_user_do_sigreturn(env, sf_addr);
     if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
         goto segv_and_exit;
@@ -316,7 +284,7 @@ long do_sigreturn(CPUSPARCState *env)
         __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
     }
     for (i=0; i < 8; i++) {
-        __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
+        __get_user(env->regwptr[i + WREG_O0], &sf->info.si_regs.u_regs[i+8]);
     }
 
     /* FIXME: implement FPU save/restore:
@@ -433,7 +401,7 @@ void sparc64_set_context(CPUSPARCState *env)
     abi_ulong fp, i7, w_addr;
     unsigned int i;
 
-    ucp_addr = env->regwptr[UREG_I0];
+    ucp_addr = env->regwptr[WREG_O0];
     if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) {
         goto do_sigsegv;
     }
@@ -443,7 +411,7 @@ void sparc64_set_context(CPUSPARCState *env)
     if ((pc | npc) & 3) {
         goto do_sigsegv;
     }
-    if (env->regwptr[UREG_I1]) {
+    if (env->regwptr[WREG_O1]) {
         target_sigset_t target_set;
         sigset_t set;
 
@@ -474,19 +442,19 @@ void sparc64_set_context(CPUSPARCState *env)
     __get_user(env->gregs[5], (&(*grp)[SPARC_MC_G5]));
     __get_user(env->gregs[6], (&(*grp)[SPARC_MC_G6]));
     __get_user(env->gregs[7], (&(*grp)[SPARC_MC_G7]));
-    __get_user(env->regwptr[UREG_I0], (&(*grp)[SPARC_MC_O0]));
-    __get_user(env->regwptr[UREG_I1], (&(*grp)[SPARC_MC_O1]));
-    __get_user(env->regwptr[UREG_I2], (&(*grp)[SPARC_MC_O2]));
-    __get_user(env->regwptr[UREG_I3], (&(*grp)[SPARC_MC_O3]));
-    __get_user(env->regwptr[UREG_I4], (&(*grp)[SPARC_MC_O4]));
-    __get_user(env->regwptr[UREG_I5], (&(*grp)[SPARC_MC_O5]));
-    __get_user(env->regwptr[UREG_I6], (&(*grp)[SPARC_MC_O6]));
-    __get_user(env->regwptr[UREG_I7], (&(*grp)[SPARC_MC_O7]));
+    __get_user(env->regwptr[WREG_O0], (&(*grp)[SPARC_MC_O0]));
+    __get_user(env->regwptr[WREG_O1], (&(*grp)[SPARC_MC_O1]));
+    __get_user(env->regwptr[WREG_O2], (&(*grp)[SPARC_MC_O2]));
+    __get_user(env->regwptr[WREG_O3], (&(*grp)[SPARC_MC_O3]));
+    __get_user(env->regwptr[WREG_O4], (&(*grp)[SPARC_MC_O4]));
+    __get_user(env->regwptr[WREG_O5], (&(*grp)[SPARC_MC_O5]));
+    __get_user(env->regwptr[WREG_O6], (&(*grp)[SPARC_MC_O6]));
+    __get_user(env->regwptr[WREG_O7], (&(*grp)[SPARC_MC_O7]));
 
     __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
     __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
 
-    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
+    w_addr = TARGET_STACK_BIAS + env->regwptr[WREG_FP];
     if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
                  abi_ulong) != 0) {
         goto do_sigsegv;
@@ -534,7 +502,7 @@ void sparc64_get_context(CPUSPARCState *env)
     target_sigset_t target_set;
     sigset_t set;
 
-    ucp_addr = env->regwptr[UREG_I0];
+    ucp_addr = env->regwptr[WREG_O0];
     if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0)) {
         goto do_sigsegv;
     }
@@ -580,16 +548,16 @@ void sparc64_get_context(CPUSPARCState *env)
     __put_user(env->gregs[5], &((*grp)[SPARC_MC_G5]));
     __put_user(env->gregs[6], &((*grp)[SPARC_MC_G6]));
     __put_user(env->gregs[7], &((*grp)[SPARC_MC_G7]));
-    __put_user(env->regwptr[UREG_I0], &((*grp)[SPARC_MC_O0]));
-    __put_user(env->regwptr[UREG_I1], &((*grp)[SPARC_MC_O1]));
-    __put_user(env->regwptr[UREG_I2], &((*grp)[SPARC_MC_O2]));
-    __put_user(env->regwptr[UREG_I3], &((*grp)[SPARC_MC_O3]));
-    __put_user(env->regwptr[UREG_I4], &((*grp)[SPARC_MC_O4]));
-    __put_user(env->regwptr[UREG_I5], &((*grp)[SPARC_MC_O5]));
-    __put_user(env->regwptr[UREG_I6], &((*grp)[SPARC_MC_O6]));
-    __put_user(env->regwptr[UREG_I7], &((*grp)[SPARC_MC_O7]));
+    __put_user(env->regwptr[WREG_O0], &((*grp)[SPARC_MC_O0]));
+    __put_user(env->regwptr[WREG_O1], &((*grp)[SPARC_MC_O1]));
+    __put_user(env->regwptr[WREG_O2], &((*grp)[SPARC_MC_O2]));
+    __put_user(env->regwptr[WREG_O3], &((*grp)[SPARC_MC_O3]));
+    __put_user(env->regwptr[WREG_O4], &((*grp)[SPARC_MC_O4]));
+    __put_user(env->regwptr[WREG_O5], &((*grp)[SPARC_MC_O5]));
+    __put_user(env->regwptr[WREG_O6], &((*grp)[SPARC_MC_O6]));
+    __put_user(env->regwptr[WREG_O7], &((*grp)[SPARC_MC_O7]));
 
-    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
+    w_addr = TARGET_STACK_BIAS + env->regwptr[WREG_FP];
     fp = i7 = 0;
     if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
                  abi_ulong) != 0) {
-- 
2.17.1



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

* [Qemu-devel] [PATCH 08/13] linux-user/sparc: Fix cpu_clone_regs
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (6 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 07/13] linux-user/sparc: Use WREG constants in sparc/signal.c Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 09/13] linux-user/sparc: Flush register windows before clone/fork/vfork Richard Henderson
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

We failed to set the secondary return value in %o1
we failed to advance the PC past the syscall,
we failed to adjust regwptr into the new structure,
we stored the stack pointer into the wrong register.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/sparc/target_cpu.h | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
index 2c80db4889..a81f8216b7 100644
--- a/linux-user/sparc/target_cpu.h
+++ b/linux-user/sparc/target_cpu.h
@@ -22,22 +22,39 @@
 
 static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp)
 {
-    if (newsp) {
-        env->regwptr[22] = newsp;
-    }
-    /* syscall return for clone child: 0, and clear CF since
-     * this counts as a success return value.
+    /*
+     * After cpu_copy, env->regwptr is pointing into old_env.
+     * Update the new cpu to use its own register window.
      */
-    env->regwptr[0] = 0;
+    env->regwptr = env->regbase + (env->cwp * 16);
+
+    /* Set a new stack, if requested.  */
+    if (newsp) {
+        /* ??? The kernel appears to copy one stack frame to the new stack. */
+        /* ??? The kernel force aligns the stack. */
+        env->regwptr[WREG_SP] = newsp;
+    }
+
+    /*
+     * Syscall return for clone child: %o0 = 0 and clear CF since
+     * this counts as a success return value.  %o1 = 1 to indicate
+     * this is the child.  Advance the PC past the syscall.
+     */
+    env->regwptr[WREG_O0] = 0;
 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
     env->xcc &= ~PSR_CARRY;
 #else
     env->psr &= ~PSR_CARRY;
 #endif
+    env->regwptr[WREG_O1] = 1;
+    env->pc = env->npc;
+    env->npc = env->npc + 4;
 }
 
 static inline void cpu_clone_regs_parent(CPUSPARCState *env)
 {
+    /* Set the second return value for the parent: %o1 = 0.  */
+    env->regwptr[WREG_O1] = 0;
 }
 
 static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
-- 
2.17.1



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

* [Qemu-devel] [PATCH 09/13] linux-user/sparc: Flush register windows before clone/fork/vfork
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (7 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 08/13] linux-user/sparc: Fix cpu_clone_regs Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 10/13] scripts/qemu-binfmt-conf: Update for sparc64 Richard Henderson
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

As seen as the very first instruction of sys_clone in the kernel.

Ideally this would be done in or before cpu_copy, and not with a
separate explicit test vs the syscall number, but this is a more
minimal solution.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/sparc/cpu_loop.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index 9e357229c0..0816da6fa1 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -169,6 +169,18 @@ void cpu_loop (CPUSPARCState *env)
         case 0x110:
         case 0x16d:
 #endif
+            /*
+             * Before copying/adjusting registers for parent/child,
+             * flush the register windows to the stack.
+             */
+            switch (env->gregs[1]) {
+            case TARGET_NR_fork:
+            case TARGET_NR_vfork:
+            case TARGET_NR_clone:
+                flush_windows(env);
+                break;
+            }
+
             ret = do_syscall (env, env->gregs[1],
                               env->regwptr[0], env->regwptr[1],
                               env->regwptr[2], env->regwptr[3],
-- 
2.17.1



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

* [Qemu-devel] [PATCH 10/13] scripts/qemu-binfmt-conf: Update for sparc64
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (8 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 09/13] linux-user/sparc: Flush register windows before clone/fork/vfork Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-06-13 15:22   ` Laurent Vivier
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 11/13] tests/tcg/multiarch/linux-test: Fix error check for shmat Richard Henderson
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Also note that we were missing the qemu_target_list entry
for plain sparc; fix that at the same time.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 scripts/qemu-binfmt-conf.sh | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index b5a16742a1..9f1580a91c 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
 # Enable automatic program execution by the kernel.
 
-qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
-mips mipsel mipsn32 mipsn32el mips64 mips64el \
+qemu_target_list="i386 i486 alpha arm armeb sparc sparc32plus sparc64 \
+ppc ppc64 ppc64le m68k mips mipsel mipsn32 mipsn32el mips64 mips64el \
 sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \
 microblaze microblazeel or1k x86_64"
 
@@ -38,6 +38,10 @@ sparc32plus_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
 sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
 sparc32plus_family=sparc
 
+sparc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2b'
+sparc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
+sparc64_family=sparc
+
 ppc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
 ppc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
 ppc_family=ppc
-- 
2.17.1



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

* [Qemu-devel] [PATCH 11/13] tests/tcg/multiarch/linux-test: Fix error check for shmat
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (9 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 10/13] scripts/qemu-binfmt-conf: Update for sparc64 Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-06-13 15:08   ` Laurent Vivier
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 12/13] linux-user: Fix shmat emulation by honoring host SHMLBA Richard Henderson
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

The error indicator for this syscall is -1, not 0.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tests/tcg/multiarch/linux-test.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/tcg/multiarch/linux-test.c b/tests/tcg/multiarch/linux-test.c
index fa4243fc04..673d7c8a1c 100644
--- a/tests/tcg/multiarch/linux-test.c
+++ b/tests/tcg/multiarch/linux-test.c
@@ -503,8 +503,9 @@ static void test_shm(void)
 
     shmid = chk_error(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0777));
     ptr = shmat(shmid, NULL, 0);
-    if (!ptr)
+    if (ptr == (void *)-1) {
         error("shmat");
+    }
 
     memset(ptr, 0, SHM_SIZE);
 
-- 
2.17.1



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

* [Qemu-devel] [PATCH 12/13] linux-user: Fix shmat emulation by honoring host SHMLBA
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (10 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 11/13] tests/tcg/multiarch/linux-test: Fix error check for shmat Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-05-22  9:40   ` Laurent Vivier
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 13/13] linux-user: Align mmap_find_vma to host page size Richard Henderson
  2019-06-11 20:53 ` [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
  13 siblings, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

For those hosts with SHMLBA > getpagesize, we don't automatically
select a guest address that is compatible with the host.  We can
achieve this by boosting the alignment of guest_base and by adding
an extra alignment argument to mmap_find_vma.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/qemu.h    |  2 +-
 linux-user/elfload.c | 17 +++++-----
 linux-user/mmap.c    | 74 +++++++++++++++++++++++---------------------
 linux-user/syscall.c |  3 +-
 4 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index ef400cb78a..82d33d7e93 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -443,7 +443,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
                        abi_ulong new_addr);
 extern unsigned long last_brk;
 extern abi_ulong mmap_next_start;
-abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
+abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong);
 void mmap_fork_start(void);
 void mmap_fork_end(int child);
 
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ef42e02d82..fe9f07843e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -3,6 +3,7 @@
 #include <sys/param.h>
 
 #include <sys/resource.h>
+#include <sys/shm.h>
 
 #include "qemu.h"
 #include "disas/disas.h"
@@ -2012,6 +2013,8 @@ unsigned long init_guest_space(unsigned long host_start,
                                unsigned long guest_start,
                                bool fixed)
 {
+    /* In order to use host shmat, we must be able to honor SHMLBA.  */
+    unsigned long align = MAX(SHMLBA, qemu_host_page_size);
     unsigned long current_start, aligned_start;
     int flags;
 
@@ -2029,7 +2032,7 @@ unsigned long init_guest_space(unsigned long host_start,
     }
 
     /* Setup the initial flags and start address.  */
-    current_start = host_start & qemu_host_page_mask;
+    current_start = host_start & -align;
     flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;
     if (fixed) {
         flags |= MAP_FIXED;
@@ -2065,8 +2068,8 @@ unsigned long init_guest_space(unsigned long host_start,
             return (unsigned long)-1;
         }
         munmap((void *)real_start, host_full_size);
-        if (real_start & ~qemu_host_page_mask) {
-            /* The same thing again, but with an extra qemu_host_page_size
+        if (real_start & (align - 1)) {
+            /* The same thing again, but with extra
              * so that we can shift around alignment.
              */
             unsigned long real_size = host_full_size + qemu_host_page_size;
@@ -2079,7 +2082,7 @@ unsigned long init_guest_space(unsigned long host_start,
                 return (unsigned long)-1;
             }
             munmap((void *)real_start, real_size);
-            real_start = HOST_PAGE_ALIGN(real_start);
+            real_start = ROUND_UP(real_start, align);
         }
         current_start = real_start;
     }
@@ -2106,7 +2109,7 @@ unsigned long init_guest_space(unsigned long host_start,
         }
 
         /* Ensure the address is properly aligned.  */
-        if (real_start & ~qemu_host_page_mask) {
+        if (real_start & (align - 1)) {
             /* Ideally, we adjust like
              *
              *    pages: [  ][  ][  ][  ][  ]
@@ -2134,7 +2137,7 @@ unsigned long init_guest_space(unsigned long host_start,
             if (real_start == (unsigned long)-1) {
                 return (unsigned long)-1;
             }
-            aligned_start = HOST_PAGE_ALIGN(real_start);
+            aligned_start = ROUND_UP(real_start, align);
         } else {
             aligned_start = real_start;
         }
@@ -2171,7 +2174,7 @@ unsigned long init_guest_space(unsigned long host_start,
          * because of trouble with ARM commpage setup.
          */
         munmap((void *)real_start, real_size);
-        current_start += qemu_host_page_size;
+        current_start += align;
         if (host_start == current_start) {
             /* Theoretically possible if host doesn't have any suitably
              * aligned areas.  Normally the first mmap will fail.
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index e0249efe4f..10796b37ac 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -202,49 +202,52 @@ unsigned long last_brk;
 
 /* Subroutine of mmap_find_vma, used when we have pre-allocated a chunk
    of guest address space.  */
-static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
+static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
+                                        abi_ulong align)
 {
-    abi_ulong addr;
-    abi_ulong end_addr;
+    abi_ulong addr, end_addr, incr = qemu_host_page_size;
     int prot;
-    int looped = 0;
+    bool looped = false;
 
     if (size > reserved_va) {
         return (abi_ulong)-1;
     }
 
-    size = HOST_PAGE_ALIGN(size);
-    end_addr = start + size;
-    if (end_addr > reserved_va) {
-        end_addr = reserved_va;
-    }
-    addr = end_addr - qemu_host_page_size;
+    /* Note that start and size have already been aligned by mmap_find_vma. */
 
+    end_addr = start + size;
+    if (start > reserved_va - size) {
+        /* Start at the top of the address space.  */
+        end_addr = ((reserved_va - size) & -align) + size;
+        looped = true;
+    }
+
+    /* Search downward from END_ADDR, checking to see if a page is in use.  */
+    addr = end_addr;
     while (1) {
+        addr -= incr;
         if (addr > end_addr) {
             if (looped) {
+                /* Failure.  The entire address space has been searched.  */
                 return (abi_ulong)-1;
             }
-            end_addr = reserved_va;
-            addr = end_addr - qemu_host_page_size;
-            looped = 1;
-            continue;
+            /* Re-start at the top of the address space.  */
+            addr = end_addr = ((reserved_va - size) & -align) + size;
+            looped = true;
+        } else {
+            prot = page_get_flags(addr);
+            if (prot) {
+                /* Page in use.  Restart below this page.  */
+                addr = end_addr = ((addr - size) & -align) + size;
+            } else if (addr && addr + size == end_addr) {
+                /* Success!  All pages between ADDR and END_ADDR are free.  */
+                if (start == mmap_next_start) {
+                    mmap_next_start = addr;
+                }
+                return addr;
+            }
         }
-        prot = page_get_flags(addr);
-        if (prot) {
-            end_addr = addr;
-        }
-        if (addr && addr + size == end_addr) {
-            break;
-        }
-        addr -= qemu_host_page_size;
     }
-
-    if (start == mmap_next_start) {
-        mmap_next_start = addr;
-    }
-
-    return addr;
 }
 
 /*
@@ -253,7 +256,7 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
  * It must be called with mmap_lock() held.
  * Return -1 if error.
  */
-abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
+abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
 {
     void *ptr, *prev;
     abi_ulong addr;
@@ -265,11 +268,12 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
     } else {
         start &= qemu_host_page_mask;
     }
+    start = ROUND_UP(start, align);
 
     size = HOST_PAGE_ALIGN(size);
 
     if (reserved_va) {
-        return mmap_find_vma_reserved(start, size);
+        return mmap_find_vma_reserved(start, size, align);
     }
 
     addr = start;
@@ -299,7 +303,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
         if (h2g_valid(ptr + size - 1)) {
             addr = h2g(ptr);
 
-            if ((addr & ~TARGET_PAGE_MASK) == 0) {
+            if ((addr & (align - 1)) == 0) {
                 /* Success.  */
                 if (start == mmap_next_start && addr >= TASK_UNMAPPED_BASE) {
                     mmap_next_start = addr + size;
@@ -313,12 +317,12 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
                 /* Assume the result that the kernel gave us is the
                    first with enough free space, so start again at the
                    next higher target page.  */
-                addr = TARGET_PAGE_ALIGN(addr);
+                addr = ROUND_UP(addr, align);
                 break;
             case 1:
                 /* Sometimes the kernel decides to perform the allocation
                    at the top end of memory instead.  */
-                addr &= TARGET_PAGE_MASK;
+                addr &= -align;
                 break;
             case 2:
                 /* Start over at low memory.  */
@@ -416,7 +420,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
     if (!(flags & MAP_FIXED)) {
         host_len = len + offset - host_offset;
         host_len = HOST_PAGE_ALIGN(host_len);
-        start = mmap_find_vma(real_start, host_len);
+        start = mmap_find_vma(real_start, host_len, TARGET_PAGE_SIZE);
         if (start == (abi_ulong)-1) {
             errno = ENOMEM;
             goto fail;
@@ -710,7 +714,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
     } else if (flags & MREMAP_MAYMOVE) {
         abi_ulong mmap_start;
 
-        mmap_start = mmap_find_vma(0, new_size);
+        mmap_start = mmap_find_vma(0, new_size, TARGET_PAGE_SIZE);
 
         if (mmap_start == -1) {
             errno = ENOMEM;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f960556bf8..1feb740f66 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3912,7 +3912,8 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
     else {
         abi_ulong mmap_start;
 
-        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
+        /* In order to use the host shmat, we need to honor host SHMLBA.  */
+        mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba));
 
         if (mmap_start == -1) {
             errno = ENOMEM;
-- 
2.17.1



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

* [Qemu-devel] [PATCH 13/13] linux-user: Align mmap_find_vma to host page size
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (11 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 12/13] linux-user: Fix shmat emulation by honoring host SHMLBA Richard Henderson
@ 2019-05-19 20:19 ` Richard Henderson
  2019-05-22  9:45   ` Laurent Vivier
  2019-06-11 20:53 ` [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
  13 siblings, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2019-05-19 20:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

This can avoid stack allocation failures for i386 guest
on ppc64 (64k page) host.

Suggested-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/mmap.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 10796b37ac..af41339d57 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -262,6 +262,8 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
     abi_ulong addr;
     int wrapped, repeat;
 
+    align = MAX(align, qemu_host_page_size);
+
     /* If 'start' == 0, then a default start address is used. */
     if (start == 0) {
         start = mmap_next_start;
-- 
2.17.1



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

* Re: [Qemu-devel] [PATCH 12/13] linux-user: Fix shmat emulation by honoring host SHMLBA
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 12/13] linux-user: Fix shmat emulation by honoring host SHMLBA Richard Henderson
@ 2019-05-22  9:40   ` Laurent Vivier
  0 siblings, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-05-22  9:40 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

On 19/05/2019 22:19, Richard Henderson wrote:
> For those hosts with SHMLBA > getpagesize, we don't automatically
> select a guest address that is compatible with the host.  We can
> achieve this by boosting the alignment of guest_base and by adding
> an extra alignment argument to mmap_find_vma.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   linux-user/qemu.h    |  2 +-
>   linux-user/elfload.c | 17 +++++-----
>   linux-user/mmap.c    | 74 +++++++++++++++++++++++---------------------
>   linux-user/syscall.c |  3 +-
>   4 files changed, 52 insertions(+), 44 deletions(-)
> 
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index ef400cb78a..82d33d7e93 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -443,7 +443,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
>                          abi_ulong new_addr);
>   extern unsigned long last_brk;
>   extern abi_ulong mmap_next_start;
> -abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
> +abi_ulong mmap_find_vma(abi_ulong, abi_ulong, abi_ulong);
>   void mmap_fork_start(void);
>   void mmap_fork_end(int child);
>   
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index ef42e02d82..fe9f07843e 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -3,6 +3,7 @@
>   #include <sys/param.h>
>   
>   #include <sys/resource.h>
> +#include <sys/shm.h>
>   
>   #include "qemu.h"
>   #include "disas/disas.h"
> @@ -2012,6 +2013,8 @@ unsigned long init_guest_space(unsigned long host_start,
>                                  unsigned long guest_start,
>                                  bool fixed)
>   {
> +    /* In order to use host shmat, we must be able to honor SHMLBA.  */
> +    unsigned long align = MAX(SHMLBA, qemu_host_page_size);
>       unsigned long current_start, aligned_start;
>       int flags;
>   
> @@ -2029,7 +2032,7 @@ unsigned long init_guest_space(unsigned long host_start,
>       }
>   
>       /* Setup the initial flags and start address.  */
> -    current_start = host_start & qemu_host_page_mask;
> +    current_start = host_start & -align;
>       flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;
>       if (fixed) {
>           flags |= MAP_FIXED;
> @@ -2065,8 +2068,8 @@ unsigned long init_guest_space(unsigned long host_start,
>               return (unsigned long)-1;
>           }
>           munmap((void *)real_start, host_full_size);
> -        if (real_start & ~qemu_host_page_mask) {
> -            /* The same thing again, but with an extra qemu_host_page_size
> +        if (real_start & (align - 1)) {
> +            /* The same thing again, but with extra
>                * so that we can shift around alignment.
>                */
>               unsigned long real_size = host_full_size + qemu_host_page_size;
> @@ -2079,7 +2082,7 @@ unsigned long init_guest_space(unsigned long host_start,
>                   return (unsigned long)-1;
>               }
>               munmap((void *)real_start, real_size);
> -            real_start = HOST_PAGE_ALIGN(real_start);
> +            real_start = ROUND_UP(real_start, align);
>           }
>           current_start = real_start;
>       }
> @@ -2106,7 +2109,7 @@ unsigned long init_guest_space(unsigned long host_start,
>           }
>   
>           /* Ensure the address is properly aligned.  */
> -        if (real_start & ~qemu_host_page_mask) {
> +        if (real_start & (align - 1)) {
>               /* Ideally, we adjust like
>                *
>                *    pages: [  ][  ][  ][  ][  ]
> @@ -2134,7 +2137,7 @@ unsigned long init_guest_space(unsigned long host_start,
>               if (real_start == (unsigned long)-1) {
>                   return (unsigned long)-1;
>               }
> -            aligned_start = HOST_PAGE_ALIGN(real_start);
> +            aligned_start = ROUND_UP(real_start, align);
>           } else {
>               aligned_start = real_start;
>           }
> @@ -2171,7 +2174,7 @@ unsigned long init_guest_space(unsigned long host_start,
>            * because of trouble with ARM commpage setup.
>            */
>           munmap((void *)real_start, real_size);
> -        current_start += qemu_host_page_size;
> +        current_start += align;
>           if (host_start == current_start) {
>               /* Theoretically possible if host doesn't have any suitably
>                * aligned areas.  Normally the first mmap will fail.
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index e0249efe4f..10796b37ac 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -202,49 +202,52 @@ unsigned long last_brk;
>   
>   /* Subroutine of mmap_find_vma, used when we have pre-allocated a chunk
>      of guest address space.  */
> -static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
> +static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
> +                                        abi_ulong align)
>   {
> -    abi_ulong addr;
> -    abi_ulong end_addr;
> +    abi_ulong addr, end_addr, incr = qemu_host_page_size;
>       int prot;
> -    int looped = 0;
> +    bool looped = false;
>   
>       if (size > reserved_va) {
>           return (abi_ulong)-1;
>       }
>   
> -    size = HOST_PAGE_ALIGN(size);
> -    end_addr = start + size;
> -    if (end_addr > reserved_va) {
> -        end_addr = reserved_va;
> -    }
> -    addr = end_addr - qemu_host_page_size;
> +    /* Note that start and size have already been aligned by mmap_find_vma. */
>   
> +    end_addr = start + size;
> +    if (start > reserved_va - size) {
> +        /* Start at the top of the address space.  */
> +        end_addr = ((reserved_va - size) & -align) + size;
> +        looped = true;
> +    }
> +
> +    /* Search downward from END_ADDR, checking to see if a page is in use.  */
> +    addr = end_addr;
>       while (1) {
> +        addr -= incr;
>           if (addr > end_addr) {
>               if (looped) {
> +                /* Failure.  The entire address space has been searched.  */
>                   return (abi_ulong)-1;
>               }
> -            end_addr = reserved_va;
> -            addr = end_addr - qemu_host_page_size;
> -            looped = 1;
> -            continue;
> +            /* Re-start at the top of the address space.  */
> +            addr = end_addr = ((reserved_va - size) & -align) + size;
> +            looped = true;
> +        } else {
> +            prot = page_get_flags(addr);
> +            if (prot) {
> +                /* Page in use.  Restart below this page.  */
> +                addr = end_addr = ((addr - size) & -align) + size;
> +            } else if (addr && addr + size == end_addr) {
> +                /* Success!  All pages between ADDR and END_ADDR are free.  */
> +                if (start == mmap_next_start) {
> +                    mmap_next_start = addr;
> +                }
> +                return addr;
> +            }
>           }
> -        prot = page_get_flags(addr);
> -        if (prot) {
> -            end_addr = addr;
> -        }
> -        if (addr && addr + size == end_addr) {
> -            break;
> -        }
> -        addr -= qemu_host_page_size;
>       }
> -
> -    if (start == mmap_next_start) {
> -        mmap_next_start = addr;
> -    }
> -
> -    return addr;
>   }
>   
>   /*
> @@ -253,7 +256,7 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
>    * It must be called with mmap_lock() held.
>    * Return -1 if error.
>    */
> -abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
> +abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
>   {
>       void *ptr, *prev;
>       abi_ulong addr;
> @@ -265,11 +268,12 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
>       } else {
>           start &= qemu_host_page_mask;
>       }
> +    start = ROUND_UP(start, align);
>   
>       size = HOST_PAGE_ALIGN(size);
>   
>       if (reserved_va) {
> -        return mmap_find_vma_reserved(start, size);
> +        return mmap_find_vma_reserved(start, size, align);
>       }
>   
>       addr = start;
> @@ -299,7 +303,7 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
>           if (h2g_valid(ptr + size - 1)) {
>               addr = h2g(ptr);
>   
> -            if ((addr & ~TARGET_PAGE_MASK) == 0) {
> +            if ((addr & (align - 1)) == 0) {
>                   /* Success.  */
>                   if (start == mmap_next_start && addr >= TASK_UNMAPPED_BASE) {
>                       mmap_next_start = addr + size;
> @@ -313,12 +317,12 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
>                   /* Assume the result that the kernel gave us is the
>                      first with enough free space, so start again at the
>                      next higher target page.  */
> -                addr = TARGET_PAGE_ALIGN(addr);
> +                addr = ROUND_UP(addr, align);
>                   break;
>               case 1:
>                   /* Sometimes the kernel decides to perform the allocation
>                      at the top end of memory instead.  */
> -                addr &= TARGET_PAGE_MASK;
> +                addr &= -align;
>                   break;
>               case 2:
>                   /* Start over at low memory.  */
> @@ -416,7 +420,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
>       if (!(flags & MAP_FIXED)) {
>           host_len = len + offset - host_offset;
>           host_len = HOST_PAGE_ALIGN(host_len);
> -        start = mmap_find_vma(real_start, host_len);
> +        start = mmap_find_vma(real_start, host_len, TARGET_PAGE_SIZE);
>           if (start == (abi_ulong)-1) {
>               errno = ENOMEM;
>               goto fail;
> @@ -710,7 +714,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
>       } else if (flags & MREMAP_MAYMOVE) {
>           abi_ulong mmap_start;
>   
> -        mmap_start = mmap_find_vma(0, new_size);
> +        mmap_start = mmap_find_vma(0, new_size, TARGET_PAGE_SIZE);
>   
>           if (mmap_start == -1) {
>               errno = ENOMEM;
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index f960556bf8..1feb740f66 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -3912,7 +3912,8 @@ static inline abi_ulong do_shmat(CPUArchState *cpu_env,
>       else {
>           abi_ulong mmap_start;
>   
> -        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
> +        /* In order to use the host shmat, we need to honor host SHMLBA.  */
> +        mmap_start = mmap_find_vma(0, shm_info.shm_segsz, MAX(SHMLBA, shmlba));
>   
>           if (mmap_start == -1) {
>               errno = ENOMEM;
> 

Applied to my linux-user branch.

Thanks,
Laurent


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

* Re: [Qemu-devel] [PATCH 13/13] linux-user: Align mmap_find_vma to host page size
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 13/13] linux-user: Align mmap_find_vma to host page size Richard Henderson
@ 2019-05-22  9:45   ` Laurent Vivier
  0 siblings, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-05-22  9:45 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

On 19/05/2019 22:19, Richard Henderson wrote:
> This can avoid stack allocation failures for i386 guest
> on ppc64 (64k page) host.
> 
> Suggested-by: Laurent Vivier <laurent@vivier.eu>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   linux-user/mmap.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/linux-user/mmap.c b/linux-user/mmap.c
> index 10796b37ac..af41339d57 100644
> --- a/linux-user/mmap.c
> +++ b/linux-user/mmap.c
> @@ -262,6 +262,8 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
>       abi_ulong addr;
>       int wrapped, repeat;
>   
> +    align = MAX(align, qemu_host_page_size);
> +
>       /* If 'start' == 0, then a default start address is used. */
>       if (start == 0) {
>           start = mmap_next_start;
> 

Applied to my linux-user branch.

Thanks,
Laurent


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

* Re: [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes
  2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
                   ` (12 preceding siblings ...)
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 13/13] linux-user: Align mmap_find_vma to host page size Richard Henderson
@ 2019-06-11 20:53 ` Richard Henderson
  13 siblings, 0 replies; 25+ messages in thread
From: Richard Henderson @ 2019-06-11 20:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: laurent

Laurent has merged the final two patches, but ping for the first 11.

I see there are trivial patch conflicts with master, but I'd rather
respin with substantive review if possible.


r~


On 5/19/19 1:19 PM, Richard Henderson wrote:
> This is an omnibus patchset of:
> 
>   v2: util/path: Do not cache all filenames at startup
>   https://lists.gnu.org/archive/html/qemu-devel/2019-04/msg04149.html
> 
>   v1: linux-user: Fix shmat emulation by honoring host SHMLBA
>   https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg03430.html
> 
> And a v3 update of
> 
>   v2: linux-user sparc fixes
>   https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg02273.html
> 
> 
> r~
> 
> 
> Richard Henderson (13):
>   util/path: Do not cache all filenames at startup
>   linux-user: Rename cpu_clone_regs to cpu_clone_regs_child
>   linux-user: Introduce cpu_clone_regs_parent
>   linux-user/alpha: Set r20 secondary return value
>   target/sparc: Define an enumeration for accessing env->regwptr
>   linux-user/sparc: Use WREG constants in sparc/target_cpu.h
>   linux-user/sparc: Use WREG constants in sparc/signal.c
>   linux-user/sparc: Fix cpu_clone_regs
>   linux-user/sparc: Flush register windows before clone/fork/vfork
>   scripts/qemu-binfmt-conf: Update for sparc64
>   tests/tcg/multiarch/linux-test: Fix error check for shmat
>   linux-user: Fix shmat emulation by honoring host SHMLBA
>   linux-user: Align mmap_find_vma to host page size
> 
>  linux-user/aarch64/target_cpu.h    |   6 +-
>  linux-user/alpha/target_cpu.h      |   8 +-
>  linux-user/arm/target_cpu.h        |   6 +-
>  linux-user/cris/target_cpu.h       |   6 +-
>  linux-user/hppa/target_cpu.h       |   6 +-
>  linux-user/i386/target_cpu.h       |   6 +-
>  linux-user/m68k/target_cpu.h       |   6 +-
>  linux-user/microblaze/target_cpu.h |   6 +-
>  linux-user/mips/target_cpu.h       |   6 +-
>  linux-user/nios2/target_cpu.h      |   6 +-
>  linux-user/openrisc/target_cpu.h   |   7 +-
>  linux-user/ppc/target_cpu.h        |   6 +-
>  linux-user/qemu.h                  |   2 +-
>  linux-user/riscv/target_cpu.h      |   6 +-
>  linux-user/s390x/target_cpu.h      |   6 +-
>  linux-user/sh4/target_cpu.h        |   6 +-
>  linux-user/sparc/target_cpu.h      |  45 ++++---
>  linux-user/tilegx/target_cpu.h     |   6 +-
>  linux-user/xtensa/target_cpu.h     |   7 +-
>  target/sparc/cpu.h                 |  33 +++++
>  linux-user/elfload.c               |  17 ++-
>  linux-user/mmap.c                  |  76 ++++++-----
>  linux-user/sparc/cpu_loop.c        |  12 ++
>  linux-user/sparc/signal.c          |  96 +++++---------
>  linux-user/syscall.c               |   9 +-
>  tests/tcg/multiarch/linux-test.c   |   3 +-
>  util/path.c                        | 201 +++++++----------------------
>  scripts/qemu-binfmt-conf.sh        |   8 +-
>  28 files changed, 309 insertions(+), 299 deletions(-)
> 



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

* Re: [Qemu-devel] [PATCH 01/13] util/path: Do not cache all filenames at startup
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 01/13] util/path: Do not cache all filenames at startup Richard Henderson
@ 2019-06-13 13:40   ` Laurent Vivier
  0 siblings, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-06-13 13:40 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 19/05/2019 à 22:19, Richard Henderson a écrit :
> If one uses -L $PATH to point to a full chroot, the startup time
> is significant.  In addition, the existing probing algorithm fails
> to handle symlink loops.
> 
> Instead, probe individual paths on demand.  Cache both positive
> and negative results within $PATH, so that any one filename is
> probed only once.
> 
> Use glib filename functions for clarity.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  util/path.c | 201 ++++++++++++----------------------------------------
>  1 file changed, 47 insertions(+), 154 deletions(-)
> 
> diff --git a/util/path.c b/util/path.c
> index 7f9fc272fb..8e174eb436 100644
> --- a/util/path.c
> +++ b/util/path.c
> @@ -8,170 +8,63 @@
>  #include <dirent.h>
>  #include "qemu/cutils.h"
>  #include "qemu/path.h"
> +#include "qemu/thread.h"
>  
> -struct pathelem
> -{
> -    /* Name of this, eg. lib */
> -    char *name;
> -    /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
> -    char *pathname;
> -    struct pathelem *parent;
> -    /* Children */
> -    unsigned int num_entries;
> -    struct pathelem *entries[0];
> -};
> -
> -static struct pathelem *base;
> -
> -/* First N chars of S1 match S2, and S2 is N chars long. */
> -static int strneq(const char *s1, unsigned int n, const char *s2)
> -{
> -    unsigned int i;
> -
> -    for (i = 0; i < n; i++)
> -        if (s1[i] != s2[i])
> -            return 0;
> -    return s2[i] == 0;
> -}
> -
> -static struct pathelem *add_entry(struct pathelem *root, const char *name,
> -                                  unsigned type);
> -
> -static struct pathelem *new_entry(const char *root,
> -                                  struct pathelem *parent,
> -                                  const char *name)
> -{
> -    struct pathelem *new = g_malloc(sizeof(*new));
> -    new->name = g_strdup(name);
> -    new->pathname = g_strdup_printf("%s/%s", root, name);
> -    new->num_entries = 0;
> -    return new;
> -}
> -
> -#define streq(a,b) (strcmp((a), (b)) == 0)
> -
> -/* Not all systems provide this feature */
> -#if defined(DT_DIR) && defined(DT_UNKNOWN) && defined(DT_LNK)
> -# define dirent_type(dirent) ((dirent)->d_type)
> -# define is_dir_maybe(type) \
> -    ((type) == DT_DIR || (type) == DT_UNKNOWN || (type) == DT_LNK)
> -#else
> -# define dirent_type(dirent) (1)
> -# define is_dir_maybe(type)  (type)
> -#endif
> -
> -static struct pathelem *add_dir_maybe(struct pathelem *path)
> -{
> -    DIR *dir;
> -
> -    if ((dir = opendir(path->pathname)) != NULL) {
> -        struct dirent *dirent;
> -
> -        while ((dirent = readdir(dir)) != NULL) {
> -            if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
> -                path = add_entry(path, dirent->d_name, dirent_type(dirent));
> -            }
> -        }
> -        closedir(dir);
> -    }
> -    return path;
> -}
> -
> -static struct pathelem *add_entry(struct pathelem *root, const char *name,
> -                                  unsigned type)
> -{
> -    struct pathelem **e;
> -
> -    root->num_entries++;
> -
> -    root = g_realloc(root, sizeof(*root)
> -                   + sizeof(root->entries[0])*root->num_entries);
> -    e = &root->entries[root->num_entries-1];
> -
> -    *e = new_entry(root->pathname, root, name);
> -    if (is_dir_maybe(type)) {
> -        *e = add_dir_maybe(*e);
> -    }
> -
> -    return root;
> -}
> -
> -/* This needs to be done after tree is stabilized (ie. no more reallocs!). */
> -static void set_parents(struct pathelem *child, struct pathelem *parent)
> -{
> -    unsigned int i;
> -
> -    child->parent = parent;
> -    for (i = 0; i < child->num_entries; i++)
> -        set_parents(child->entries[i], child);
> -}
> -
> -/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
> -static const char *
> -follow_path(const struct pathelem *cursor, const char *name)
> -{
> -    unsigned int i, namelen;
> -
> -    name += strspn(name, "/");
> -    namelen = strcspn(name, "/");
> -
> -    if (namelen == 0)
> -        return cursor->pathname;
> -
> -    if (strneq(name, namelen, ".."))
> -        return follow_path(cursor->parent, name + namelen);
> -
> -    if (strneq(name, namelen, "."))
> -        return follow_path(cursor, name + namelen);
> -
> -    for (i = 0; i < cursor->num_entries; i++)
> -        if (strneq(name, namelen, cursor->entries[i]->name))
> -            return follow_path(cursor->entries[i], name + namelen);
> -
> -    /* Not found */
> -    return NULL;
> -}
> +static const char *base;
> +static GHashTable *hash;
> +static QemuMutex lock;
>  
>  void init_paths(const char *prefix)
>  {
> -    char pref_buf[PATH_MAX];
> -
> -    if (prefix[0] == '\0' ||
> -        !strcmp(prefix, "/"))
> +    if (prefix[0] == '\0' || !strcmp(prefix, "/")) {
>          return;
> -
> -    if (prefix[0] != '/') {
> -        char *cwd = getcwd(NULL, 0);
> -        size_t pref_buf_len = sizeof(pref_buf);
> -
> -        if (!cwd)
> -            abort();
> -        pstrcpy(pref_buf, sizeof(pref_buf), cwd);
> -        pstrcat(pref_buf, pref_buf_len, "/");
> -        pstrcat(pref_buf, pref_buf_len, prefix);
> -        free(cwd);
> -    } else
> -        pstrcpy(pref_buf, sizeof(pref_buf), prefix + 1);
> -
> -    base = new_entry("", NULL, pref_buf);
> -    base = add_dir_maybe(base);
> -    if (base->num_entries == 0) {
> -        g_free(base->pathname);
> -        g_free(base->name);
> -        g_free(base);
> -        base = NULL;
> -    } else {
> -        set_parents(base, base);
>      }
> +
> +    if (prefix[0] == '/') {
> +        base = g_strdup(prefix);
> +    } else {
> +        char *cwd = g_get_current_dir();
> +        base = g_build_filename(cwd, prefix, NULL);
> +        g_free(cwd);
> +    }
> +
> +    hash = g_hash_table_new(g_str_hash, g_str_equal);
> +    qemu_mutex_init(&lock);
>  }
>  
>  /* Look for path in emulation dir, otherwise return name. */
>  const char *path(const char *name)
>  {
> -    /* Only do absolute paths: quick and dirty, but should mostly be OK.
> -       Could do relative by tracking cwd. */
> -    if (!base || !name || name[0] != '/')
> -        return name;
> +    gpointer key, value;
> +    const char *ret;
>  
> -    return follow_path(base, name) ?: name;
> +    /* Only do absolute paths: quick and dirty, but should mostly be OK.  */
> +    if (!base || !name || name[0] != '/') {
> +        return name;
> +    }
> +
> +    qemu_mutex_lock(&lock);
> +
> +    /* Have we looked up this file before?  */
> +    if (g_hash_table_lookup_extended(hash, name, &key, &value)) {
> +        ret = value ? value : name;
> +    } else {
> +        char *save = g_strdup(name);
> +        char *full = g_build_filename(base, name, NULL);
> +
> +        /* Look for the path; record the result, pass or fail.  */
> +        if (access(full, F_OK) == 0) {
> +            /* Exists.  */
> +            g_hash_table_insert(hash, save, full);
> +            ret = full;
> +        } else {
> +            /* Does not exist.  */
> +            g_free(full);
> +            g_hash_table_insert(hash, save, NULL);
> +            ret = name;
> +        }
> +    }
> +
> +    qemu_mutex_unlock(&lock);
> +    return ret;
>  }
> 

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

Thanks,
Laurent


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

* Re: [Qemu-devel] [PATCH 11/13] tests/tcg/multiarch/linux-test: Fix error check for shmat
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 11/13] tests/tcg/multiarch/linux-test: Fix error check for shmat Richard Henderson
@ 2019-06-13 15:08   ` Laurent Vivier
  0 siblings, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-06-13 15:08 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 19/05/2019 à 22:19, Richard Henderson a écrit :
> The error indicator for this syscall is -1, not 0.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  tests/tcg/multiarch/linux-test.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/tcg/multiarch/linux-test.c b/tests/tcg/multiarch/linux-test.c
> index fa4243fc04..673d7c8a1c 100644
> --- a/tests/tcg/multiarch/linux-test.c
> +++ b/tests/tcg/multiarch/linux-test.c
> @@ -503,8 +503,9 @@ static void test_shm(void)
>  
>      shmid = chk_error(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0777));
>      ptr = shmat(shmid, NULL, 0);
> -    if (!ptr)
> +    if (ptr == (void *)-1) {
>          error("shmat");
> +    }
>  
>      memset(ptr, 0, SHM_SIZE);
>  
> 

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


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

* Re: [Qemu-devel] [PATCH 10/13] scripts/qemu-binfmt-conf: Update for sparc64
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 10/13] scripts/qemu-binfmt-conf: Update for sparc64 Richard Henderson
@ 2019-06-13 15:22   ` Laurent Vivier
  0 siblings, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-06-13 15:22 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 19/05/2019 à 22:19, Richard Henderson a écrit :
> Also note that we were missing the qemu_target_list entry
> for plain sparc; fix that at the same time.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  scripts/qemu-binfmt-conf.sh | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
> index b5a16742a1..9f1580a91c 100755
> --- a/scripts/qemu-binfmt-conf.sh
> +++ b/scripts/qemu-binfmt-conf.sh
> @@ -1,8 +1,8 @@
>  #!/bin/sh
>  # Enable automatic program execution by the kernel.
>  
> -qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
> -mips mipsel mipsn32 mipsn32el mips64 mips64el \
> +qemu_target_list="i386 i486 alpha arm armeb sparc sparc32plus sparc64 \
> +ppc ppc64 ppc64le m68k mips mipsel mipsn32 mipsn32el mips64 mips64el \
>  sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \
>  microblaze microblazeel or1k x86_64"
>  
> @@ -38,6 +38,10 @@ sparc32plus_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
>  sparc32plus_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>  sparc32plus_family=sparc
>  
> +sparc64_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2b'
> +sparc64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
> +sparc64_family=sparc
> +
>  ppc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'
>  ppc_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
>  ppc_family=ppc
> 

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


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

* Re: [Qemu-devel] [PATCH 04/13] linux-user/alpha: Set r20 secondary return value
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 04/13] linux-user/alpha: Set r20 secondary return value Richard Henderson
@ 2019-06-13 16:23   ` Laurent Vivier
  0 siblings, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-06-13 16:23 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 19/05/2019 à 22:19, Richard Henderson a écrit :
> This value is not, as far as I know, used by any linux software,
> but it is set by the kernel and is part of the ABI.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/alpha/target_cpu.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h
> index 140a459f73..caadb54372 100644
> --- a/linux-user/alpha/target_cpu.h
> +++ b/linux-user/alpha/target_cpu.h
> @@ -26,10 +26,12 @@ static inline void cpu_clone_regs_child(CPUAlphaState *env, target_ulong newsp)
>      }
>      env->ir[IR_V0] = 0;
>      env->ir[IR_A3] = 0;
> +    env->ir[IR_A4] = 1;  /* OSF/1 secondary return: child */
>  }
>  
>  static inline void cpu_clone_regs_parent(CPUAlphaState *env)
>  {
> +    env->ir[IR_A4] = 0;  /* OSF/1 secondary return: parent */

In the kernel, r20 is only set to 0 if !(clone_flags & CLONE_SETTLS), is
this a problem here to set it unconditionally?

Thanks,
Laurent


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

* Re: [Qemu-devel] [PATCH 02/13] linux-user: Rename cpu_clone_regs to cpu_clone_regs_child
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 02/13] linux-user: Rename cpu_clone_regs to cpu_clone_regs_child Richard Henderson
@ 2019-06-13 16:25   ` Laurent Vivier
  0 siblings, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-06-13 16:25 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 19/05/2019 à 22:19, Richard Henderson a écrit :
> We will need a target-specific hook for adjusting registers
> in the parent during clone.  To avoid confusion, rename the
> one we have to make it clear it affects the child.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/aarch64/target_cpu.h    | 2 +-
>  linux-user/alpha/target_cpu.h      | 2 +-
>  linux-user/arm/target_cpu.h        | 2 +-
>  linux-user/cris/target_cpu.h       | 2 +-
>  linux-user/hppa/target_cpu.h       | 2 +-
>  linux-user/i386/target_cpu.h       | 2 +-
>  linux-user/m68k/target_cpu.h       | 2 +-
>  linux-user/microblaze/target_cpu.h | 2 +-
>  linux-user/mips/target_cpu.h       | 2 +-
>  linux-user/nios2/target_cpu.h      | 2 +-
>  linux-user/openrisc/target_cpu.h   | 3 ++-
>  linux-user/ppc/target_cpu.h        | 2 +-
>  linux-user/riscv/target_cpu.h      | 2 +-
>  linux-user/s390x/target_cpu.h      | 2 +-
>  linux-user/sh4/target_cpu.h        | 2 +-
>  linux-user/sparc/target_cpu.h      | 2 +-
>  linux-user/tilegx/target_cpu.h     | 2 +-
>  linux-user/xtensa/target_cpu.h     | 3 ++-
>  linux-user/syscall.c               | 4 ++--
>  19 files changed, 22 insertions(+), 20 deletions(-)
> 

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



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

* Re: [Qemu-devel] [PATCH 03/13] linux-user: Introduce cpu_clone_regs_parent
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 03/13] linux-user: Introduce cpu_clone_regs_parent Richard Henderson
@ 2019-06-13 16:26   ` Laurent Vivier
  2019-06-13 19:10   ` Aleksandar Markovic
  1 sibling, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-06-13 16:26 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 19/05/2019 à 22:19, Richard Henderson a écrit :
> Add an empty inline function for each target, and invoke it
> from the proper places.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/aarch64/target_cpu.h    | 4 ++++
>  linux-user/alpha/target_cpu.h      | 4 ++++
>  linux-user/arm/target_cpu.h        | 4 ++++
>  linux-user/cris/target_cpu.h       | 4 ++++
>  linux-user/hppa/target_cpu.h       | 4 ++++
>  linux-user/i386/target_cpu.h       | 4 ++++
>  linux-user/m68k/target_cpu.h       | 4 ++++
>  linux-user/microblaze/target_cpu.h | 4 ++++
>  linux-user/mips/target_cpu.h       | 4 ++++
>  linux-user/nios2/target_cpu.h      | 4 ++++
>  linux-user/openrisc/target_cpu.h   | 4 ++++
>  linux-user/ppc/target_cpu.h        | 4 ++++
>  linux-user/riscv/target_cpu.h      | 4 ++++
>  linux-user/s390x/target_cpu.h      | 4 ++++
>  linux-user/sh4/target_cpu.h        | 4 ++++
>  linux-user/sparc/target_cpu.h      | 4 ++++
>  linux-user/tilegx/target_cpu.h     | 4 ++++
>  linux-user/xtensa/target_cpu.h     | 4 ++++
>  linux-user/syscall.c               | 2 ++
>  19 files changed, 74 insertions(+)
> 

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


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

* Re: [Qemu-devel] [PATCH 03/13] linux-user: Introduce cpu_clone_regs_parent
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 03/13] linux-user: Introduce cpu_clone_regs_parent Richard Henderson
  2019-06-13 16:26   ` Laurent Vivier
@ 2019-06-13 19:10   ` Aleksandar Markovic
  1 sibling, 0 replies; 25+ messages in thread
From: Aleksandar Markovic @ 2019-06-13 19:10 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, laurent

On May 19, 2019 10:27 PM, "Richard Henderson" <richard.henderson@linaro.org>
wrote:
>
> Add an empty inline function for each target, and invoke it
> from the proper places.
>

Can we outline the meaning/purpose of the new function here?

This commit message looks horrible.

Regards,
Aleksandar

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/aarch64/target_cpu.h    | 4 ++++
>  linux-user/alpha/target_cpu.h      | 4 ++++
>  linux-user/arm/target_cpu.h        | 4 ++++
>  linux-user/cris/target_cpu.h       | 4 ++++
>  linux-user/hppa/target_cpu.h       | 4 ++++
>  linux-user/i386/target_cpu.h       | 4 ++++
>  linux-user/m68k/target_cpu.h       | 4 ++++
>  linux-user/microblaze/target_cpu.h | 4 ++++
>  linux-user/mips/target_cpu.h       | 4 ++++
>  linux-user/nios2/target_cpu.h      | 4 ++++
>  linux-user/openrisc/target_cpu.h   | 4 ++++
>  linux-user/ppc/target_cpu.h        | 4 ++++
>  linux-user/riscv/target_cpu.h      | 4 ++++
>  linux-user/s390x/target_cpu.h      | 4 ++++
>  linux-user/sh4/target_cpu.h        | 4 ++++
>  linux-user/sparc/target_cpu.h      | 4 ++++
>  linux-user/tilegx/target_cpu.h     | 4 ++++
>  linux-user/xtensa/target_cpu.h     | 4 ++++
>  linux-user/syscall.c               | 2 ++
>  19 files changed, 74 insertions(+)
>
> diff --git a/linux-user/aarch64/target_cpu.h
b/linux-user/aarch64/target_cpu.h
> index abde35b104..0182bfca07 100644
> --- a/linux-user/aarch64/target_cpu.h
> +++ b/linux-user/aarch64/target_cpu.h
> @@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUARMState
*env, target_ulong newsp)
>      env->xregs[0] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUARMState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
>  {
>      /* Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
> diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h
> index dc02f2234c..140a459f73 100644
> --- a/linux-user/alpha/target_cpu.h
> +++ b/linux-user/alpha/target_cpu.h
> @@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUAlphaState
*env, target_ulong newsp)
>      env->ir[IR_A3] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUAlphaState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
>  {
>      env->unique = newtls;
> diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
> index d35c997287..3e66d5b106 100644
> --- a/linux-user/arm/target_cpu.h
> +++ b/linux-user/arm/target_cpu.h
> @@ -31,6 +31,10 @@ static inline void cpu_clone_regs_child(CPUARMState
*env, target_ulong newsp)
>      env->regs[0] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUARMState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
>  {
>      if (access_secure_reg(env)) {
> diff --git a/linux-user/cris/target_cpu.h b/linux-user/cris/target_cpu.h
> index 9c847caaef..4da074b4fd 100644
> --- a/linux-user/cris/target_cpu.h
> +++ b/linux-user/cris/target_cpu.h
> @@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUCRISState
*env, target_ulong newsp)
>      env->regs[10] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUCRISState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUCRISState *env, target_ulong newtls)
>  {
>      env->pregs[PR_PID] = (env->pregs[PR_PID] & 0xff) | newtls;
> diff --git a/linux-user/hppa/target_cpu.h b/linux-user/hppa/target_cpu.h
> index b98e5a1cfe..6b323297af 100644
> --- a/linux-user/hppa/target_cpu.h
> +++ b/linux-user/hppa/target_cpu.h
> @@ -31,6 +31,10 @@ static inline void cpu_clone_regs_child(CPUHPPAState
*env, target_ulong newsp)
>      env->iaoq_b = env->gr[31] + 4;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUHPPAState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUHPPAState *env, target_ulong newtls)
>  {
>      env->cr[27] = newtls;
> diff --git a/linux-user/i386/target_cpu.h b/linux-user/i386/target_cpu.h
> index e1c9e03490..6dbb856c52 100644
> --- a/linux-user/i386/target_cpu.h
> +++ b/linux-user/i386/target_cpu.h
> @@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUX86State
*env, target_ulong newsp)
>      env->regs[R_EAX] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUX86State *env)
> +{
> +}
> +
>  #if defined(TARGET_ABI32)
>  abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr);
>
> diff --git a/linux-user/m68k/target_cpu.h b/linux-user/m68k/target_cpu.h
> index 7637a98cab..f1a53cdee5 100644
> --- a/linux-user/m68k/target_cpu.h
> +++ b/linux-user/m68k/target_cpu.h
> @@ -29,6 +29,10 @@ static inline void cpu_clone_regs_child(CPUM68KState
*env, target_ulong newsp)
>      env->dregs[0] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUM68KState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUM68KState *env, target_ulong newtls)
>  {
>      CPUState *cs = CPU(m68k_env_get_cpu(env));
> diff --git a/linux-user/microblaze/target_cpu.h
b/linux-user/microblaze/target_cpu.h
> index 526b80d54d..5e285e9211 100644
> --- a/linux-user/microblaze/target_cpu.h
> +++ b/linux-user/microblaze/target_cpu.h
> @@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUMBState
*env, target_ulong newsp)
>      env->regs[3] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUMBState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUMBState *env, target_ulong newtls)
>  {
>      env->regs[21] = newtls;
> diff --git a/linux-user/mips/target_cpu.h b/linux-user/mips/target_cpu.h
> index c42660b047..d0e0b1bac0 100644
> --- a/linux-user/mips/target_cpu.h
> +++ b/linux-user/mips/target_cpu.h
> @@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUMIPSState
*env, target_ulong newsp)
>      env->active_tc.gpr[2] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUMIPSState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls)
>  {
>      env->active_tc.CP0_UserLocal = newtls;
> diff --git a/linux-user/nios2/target_cpu.h b/linux-user/nios2/target_cpu.h
> index bec2ea79c4..01725ba004 100644
> --- a/linux-user/nios2/target_cpu.h
> +++ b/linux-user/nios2/target_cpu.h
> @@ -28,6 +28,10 @@ static inline void cpu_clone_regs_child(CPUNios2State
*env, target_ulong newsp)
>      env->regs[R_RET0] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUNios2State *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUNios2State *env, target_ulong newtls)
>  {
>      /*
> diff --git a/linux-user/openrisc/target_cpu.h
b/linux-user/openrisc/target_cpu.h
> index d163ba2e26..6586951c5b 100644
> --- a/linux-user/openrisc/target_cpu.h
> +++ b/linux-user/openrisc/target_cpu.h
> @@ -29,6 +29,10 @@ static inline void
cpu_clone_regs_child(CPUOpenRISCState *env,
>      cpu_set_gpr(env, 11, 0);
>  }
>
> +static inline void cpu_clone_regs_parent(CPUOpenRISCState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong
newtls)
>  {
>      cpu_set_gpr(env, 10, newtls);
> diff --git a/linux-user/ppc/target_cpu.h b/linux-user/ppc/target_cpu.h
> index 34decf3876..00c9f5eb86 100644
> --- a/linux-user/ppc/target_cpu.h
> +++ b/linux-user/ppc/target_cpu.h
> @@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUPPCState
*env, target_ulong newsp)
>      env->gpr[3] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUPPCState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUPPCState *env, target_ulong newtls)
>  {
>  #if defined(TARGET_PPC64)
> diff --git a/linux-user/riscv/target_cpu.h b/linux-user/riscv/target_cpu.h
> index d92153851c..4ef1b23b4f 100644
> --- a/linux-user/riscv/target_cpu.h
> +++ b/linux-user/riscv/target_cpu.h
> @@ -10,6 +10,10 @@ static inline void cpu_clone_regs_child(CPURISCVState
*env, target_ulong newsp)
>      env->gpr[xA0] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPURISCVState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPURISCVState *env, target_ulong newtls)
>  {
>      env->gpr[xTP] = newtls;
> diff --git a/linux-user/s390x/target_cpu.h b/linux-user/s390x/target_cpu.h
> index e0baa98e75..18e290ece8 100644
> --- a/linux-user/s390x/target_cpu.h
> +++ b/linux-user/s390x/target_cpu.h
> @@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUS390XState
*env, target_ulong newsp)
>      env->regs[2] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUS390XState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
>  {
>      env->aregs[0] = newtls >> 32;
> diff --git a/linux-user/sh4/target_cpu.h b/linux-user/sh4/target_cpu.h
> index 854955aa5a..b0e4ab23a7 100644
> --- a/linux-user/sh4/target_cpu.h
> +++ b/linux-user/sh4/target_cpu.h
> @@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUSH4State
*env, target_ulong newsp)
>      env->gregs[0] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUSH4State *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls)
>  {
>    env->gbr = newtls;
> diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
> index 8511fc3f6f..52c9d8c7db 100644
> --- a/linux-user/sparc/target_cpu.h
> +++ b/linux-user/sparc/target_cpu.h
> @@ -36,6 +36,10 @@ static inline void cpu_clone_regs_child(CPUSPARCState
*env, target_ulong newsp)
>  #endif
>  }
>
> +static inline void cpu_clone_regs_parent(CPUSPARCState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
>  {
>      env->gregs[7] = newtls;
> diff --git a/linux-user/tilegx/target_cpu.h
b/linux-user/tilegx/target_cpu.h
> index dfca8d9598..9577462821 100644
> --- a/linux-user/tilegx/target_cpu.h
> +++ b/linux-user/tilegx/target_cpu.h
> @@ -27,6 +27,10 @@ static inline void cpu_clone_regs_child(CPUTLGState
*env, target_ulong newsp)
>      env->regs[TILEGX_R_RE] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUTLGState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUTLGState *env, target_ulong newtls)
>  {
>      env->regs[TILEGX_R_TP] = newtls;
> diff --git a/linux-user/xtensa/target_cpu.h
b/linux-user/xtensa/target_cpu.h
> index f436b160c4..42e66211cf 100644
> --- a/linux-user/xtensa/target_cpu.h
> +++ b/linux-user/xtensa/target_cpu.h
> @@ -15,6 +15,10 @@ static inline void cpu_clone_regs_child(CPUXtensaState
*env,
>      env->regs[2] = 0;
>  }
>
> +static inline void cpu_clone_regs_parent(CPUXtensaState *env)
> +{
> +}
> +
>  static inline void cpu_set_tls(CPUXtensaState *env, target_ulong newtls)
>  {
>      env->uregs[THREADPTR] = newtls;
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index b9127a9601..f960556bf8 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -5535,6 +5535,7 @@ static int do_fork(CPUArchState *env, unsigned int
flags, abi_ulong newsp,
>          new_env = cpu_copy(env);
>          /* Init regs that differ from the parent.  */
>          cpu_clone_regs_child(new_env, newsp);
> +        cpu_clone_regs_parent(env);
>          new_cpu = ENV_GET_CPU(new_env);
>          new_cpu->opaque = ts;
>          ts->bprm = parent_ts->bprm;
> @@ -5630,6 +5631,7 @@ static int do_fork(CPUArchState *env, unsigned int
flags, abi_ulong newsp,
>              if (flags & CLONE_CHILD_CLEARTID)
>                  ts->child_tidptr = child_tidptr;
>          } else {
> +            cpu_clone_regs_parent(env);
>              fork_end(0);
>          }
>      }
> --
> 2.17.1
>
>

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

* Re: [Qemu-devel] [PATCH 07/13] linux-user/sparc: Use WREG constants in sparc/signal.c
  2019-05-19 20:19 ` [Qemu-devel] [PATCH 07/13] linux-user/sparc: Use WREG constants in sparc/signal.c Richard Henderson
@ 2019-06-13 21:31   ` Laurent Vivier
  0 siblings, 0 replies; 25+ messages in thread
From: Laurent Vivier @ 2019-06-13 21:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Le 19/05/2019 à 22:19, Richard Henderson a écrit :
> Remove the incorrectly defined UREG constants.
> 
> Maddeningly, in some cases we used the correct constant getting
> the env register wrong, and in other cases we used the incorrect
> constant getting the env register right.
> 
> In the case of getcontext/setcontext, we are aided by the fact
> that the "other" constant, e.g. SPARC_MC_O0, is correct.  So we
> can easily guess that the WREG_* constant on the other side
> should also be O0.

For readability, I'd like you split this patch in two:
- one with no behavior change, only with s/UREG_/WREG_/
- one using the correct constants

Thanks,
Laurent

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  linux-user/sparc/signal.c | 96 +++++++++++++--------------------------
>  1 file changed, 32 insertions(+), 64 deletions(-)
> 
> diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
> index ead169fbaa..243f237528 100644
> --- a/linux-user/sparc/signal.c
> +++ b/linux-user/sparc/signal.c
> @@ -104,20 +104,6 @@ struct target_rt_signal_frame {
>      qemu_siginfo_fpu_t  fpu_state;
>  };
>  
> -#define UREG_O0        16
> -#define UREG_O6        22
> -#define UREG_I0        0
> -#define UREG_I1        1
> -#define UREG_I2        2
> -#define UREG_I3        3
> -#define UREG_I4        4
> -#define UREG_I5        5
> -#define UREG_I6        6
> -#define UREG_I7        7
> -#define UREG_L0        8
> -#define UREG_FP        UREG_I6
> -#define UREG_SP        UREG_O6
> -
>  static inline abi_ulong get_sigframe(struct target_sigaction *sa, 
>                                       CPUSPARCState *env,
>                                       unsigned long framesize)
> @@ -159,30 +145,12 @@ setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
>          __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
>      }
>      for (i=0; i < 8; i++) {
> -        __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
> +        __put_user(env->regwptr[WREG_O0 + i], &si->si_regs.u_regs[i+8]);
>      }
>      __put_user(mask, &si->si_mask);
>      return err;
>  }
>  
> -#if 0
> -static int
> -setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
> -                 CPUSPARCState *env, unsigned long mask)
> -{
> -    int err = 0;
> -
> -    __put_user(mask, &sc->sigc_mask);
> -    __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
> -    __put_user(env->pc, &sc->sigc_pc);
> -    __put_user(env->npc, &sc->sigc_npc);
> -    __put_user(env->psr, &sc->sigc_psr);
> -    __put_user(env->gregs[1], &sc->sigc_g1);
> -    __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
> -
> -    return err;
> -}
> -#endif
>  #define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))
>  
>  void setup_frame(int sig, struct target_sigaction *ka,
> @@ -221,20 +189,20 @@ void setup_frame(int sig, struct target_sigaction *ka,
>      }
>  
>      for (i = 0; i < 8; i++) {
> -        __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
> +        __put_user(env->regwptr[i + WREG_L0], &sf->ss.locals[i]);
>      }
>      for (i = 0; i < 8; i++) {
> -        __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
> +        __put_user(env->regwptr[i + WREG_I0], &sf->ss.ins[i]);
>      }
>      if (err)
>          goto sigsegv;
>  
>      /* 3. signal handler back-trampoline and parameters */
> -    env->regwptr[UREG_FP] = sf_addr;
> -    env->regwptr[UREG_I0] = sig;
> -    env->regwptr[UREG_I1] = sf_addr +
> +    env->regwptr[WREG_FP] = sf_addr;
> +    env->regwptr[WREG_I0] = sig;
> +    env->regwptr[WREG_I1] = sf_addr +
>              offsetof(struct target_signal_frame, info);
> -    env->regwptr[UREG_I2] = sf_addr +
> +    env->regwptr[WREG_I2] = sf_addr +
>              offsetof(struct target_signal_frame, info);
>  
>      /* 4. signal handler */
> @@ -242,11 +210,11 @@ void setup_frame(int sig, struct target_sigaction *ka,
>      env->npc = (env->pc + 4);
>      /* 5. return to kernel instructions */
>      if (ka->ka_restorer) {
> -        env->regwptr[UREG_I7] = ka->ka_restorer;
> +        env->regwptr[WREG_I7] = ka->ka_restorer;
>      } else {
>          uint32_t val32;
>  
> -        env->regwptr[UREG_I7] = sf_addr +
> +        env->regwptr[WREG_I7] = sf_addr +
>                  offsetof(struct target_signal_frame, insns) - 2 * 4;
>  
>          /* mov __NR_sigreturn, %g1 */
> @@ -284,7 +252,7 @@ long do_sigreturn(CPUSPARCState *env)
>      sigset_t host_set;
>      int i;
>  
> -    sf_addr = env->regwptr[UREG_FP];
> +    sf_addr = env->regwptr[WREG_SP];
>      trace_user_do_sigreturn(env, sf_addr);
>      if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
>          goto segv_and_exit;
> @@ -316,7 +284,7 @@ long do_sigreturn(CPUSPARCState *env)
>          __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
>      }
>      for (i=0; i < 8; i++) {
> -        __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
> +        __get_user(env->regwptr[i + WREG_O0], &sf->info.si_regs.u_regs[i+8]);
>      }
>  
>      /* FIXME: implement FPU save/restore:
> @@ -433,7 +401,7 @@ void sparc64_set_context(CPUSPARCState *env)
>      abi_ulong fp, i7, w_addr;
>      unsigned int i;
>  
> -    ucp_addr = env->regwptr[UREG_I0];
> +    ucp_addr = env->regwptr[WREG_O0];
>      if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1)) {
>          goto do_sigsegv;
>      }
> @@ -443,7 +411,7 @@ void sparc64_set_context(CPUSPARCState *env)
>      if ((pc | npc) & 3) {
>          goto do_sigsegv;
>      }
> -    if (env->regwptr[UREG_I1]) {
> +    if (env->regwptr[WREG_O1]) {
>          target_sigset_t target_set;
>          sigset_t set;
>  
> @@ -474,19 +442,19 @@ void sparc64_set_context(CPUSPARCState *env)
>      __get_user(env->gregs[5], (&(*grp)[SPARC_MC_G5]));
>      __get_user(env->gregs[6], (&(*grp)[SPARC_MC_G6]));
>      __get_user(env->gregs[7], (&(*grp)[SPARC_MC_G7]));
> -    __get_user(env->regwptr[UREG_I0], (&(*grp)[SPARC_MC_O0]));
> -    __get_user(env->regwptr[UREG_I1], (&(*grp)[SPARC_MC_O1]));
> -    __get_user(env->regwptr[UREG_I2], (&(*grp)[SPARC_MC_O2]));
> -    __get_user(env->regwptr[UREG_I3], (&(*grp)[SPARC_MC_O3]));
> -    __get_user(env->regwptr[UREG_I4], (&(*grp)[SPARC_MC_O4]));
> -    __get_user(env->regwptr[UREG_I5], (&(*grp)[SPARC_MC_O5]));
> -    __get_user(env->regwptr[UREG_I6], (&(*grp)[SPARC_MC_O6]));
> -    __get_user(env->regwptr[UREG_I7], (&(*grp)[SPARC_MC_O7]));
> +    __get_user(env->regwptr[WREG_O0], (&(*grp)[SPARC_MC_O0]));
> +    __get_user(env->regwptr[WREG_O1], (&(*grp)[SPARC_MC_O1]));
> +    __get_user(env->regwptr[WREG_O2], (&(*grp)[SPARC_MC_O2]));
> +    __get_user(env->regwptr[WREG_O3], (&(*grp)[SPARC_MC_O3]));
> +    __get_user(env->regwptr[WREG_O4], (&(*grp)[SPARC_MC_O4]));
> +    __get_user(env->regwptr[WREG_O5], (&(*grp)[SPARC_MC_O5]));
> +    __get_user(env->regwptr[WREG_O6], (&(*grp)[SPARC_MC_O6]));
> +    __get_user(env->regwptr[WREG_O7], (&(*grp)[SPARC_MC_O7]));
>  
>      __get_user(fp, &(ucp->tuc_mcontext.mc_fp));
>      __get_user(i7, &(ucp->tuc_mcontext.mc_i7));
>  
> -    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
> +    w_addr = TARGET_STACK_BIAS + env->regwptr[WREG_FP];
>      if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
>                   abi_ulong) != 0) {
>          goto do_sigsegv;
> @@ -534,7 +502,7 @@ void sparc64_get_context(CPUSPARCState *env)
>      target_sigset_t target_set;
>      sigset_t set;
>  
> -    ucp_addr = env->regwptr[UREG_I0];
> +    ucp_addr = env->regwptr[WREG_O0];
>      if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0)) {
>          goto do_sigsegv;
>      }
> @@ -580,16 +548,16 @@ void sparc64_get_context(CPUSPARCState *env)
>      __put_user(env->gregs[5], &((*grp)[SPARC_MC_G5]));
>      __put_user(env->gregs[6], &((*grp)[SPARC_MC_G6]));
>      __put_user(env->gregs[7], &((*grp)[SPARC_MC_G7]));
> -    __put_user(env->regwptr[UREG_I0], &((*grp)[SPARC_MC_O0]));
> -    __put_user(env->regwptr[UREG_I1], &((*grp)[SPARC_MC_O1]));
> -    __put_user(env->regwptr[UREG_I2], &((*grp)[SPARC_MC_O2]));
> -    __put_user(env->regwptr[UREG_I3], &((*grp)[SPARC_MC_O3]));
> -    __put_user(env->regwptr[UREG_I4], &((*grp)[SPARC_MC_O4]));
> -    __put_user(env->regwptr[UREG_I5], &((*grp)[SPARC_MC_O5]));
> -    __put_user(env->regwptr[UREG_I6], &((*grp)[SPARC_MC_O6]));
> -    __put_user(env->regwptr[UREG_I7], &((*grp)[SPARC_MC_O7]));
> +    __put_user(env->regwptr[WREG_O0], &((*grp)[SPARC_MC_O0]));
> +    __put_user(env->regwptr[WREG_O1], &((*grp)[SPARC_MC_O1]));
> +    __put_user(env->regwptr[WREG_O2], &((*grp)[SPARC_MC_O2]));
> +    __put_user(env->regwptr[WREG_O3], &((*grp)[SPARC_MC_O3]));
> +    __put_user(env->regwptr[WREG_O4], &((*grp)[SPARC_MC_O4]));
> +    __put_user(env->regwptr[WREG_O5], &((*grp)[SPARC_MC_O5]));
> +    __put_user(env->regwptr[WREG_O6], &((*grp)[SPARC_MC_O6]));
> +    __put_user(env->regwptr[WREG_O7], &((*grp)[SPARC_MC_O7]));
>  
> -    w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
> +    w_addr = TARGET_STACK_BIAS + env->regwptr[WREG_FP];
>      fp = i7 = 0;
>      if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
>                   abi_ulong) != 0) {
> 



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

end of thread, other threads:[~2019-06-13 21:42 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-19 20:19 [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson
2019-05-19 20:19 ` [Qemu-devel] [PATCH 01/13] util/path: Do not cache all filenames at startup Richard Henderson
2019-06-13 13:40   ` Laurent Vivier
2019-05-19 20:19 ` [Qemu-devel] [PATCH 02/13] linux-user: Rename cpu_clone_regs to cpu_clone_regs_child Richard Henderson
2019-06-13 16:25   ` Laurent Vivier
2019-05-19 20:19 ` [Qemu-devel] [PATCH 03/13] linux-user: Introduce cpu_clone_regs_parent Richard Henderson
2019-06-13 16:26   ` Laurent Vivier
2019-06-13 19:10   ` Aleksandar Markovic
2019-05-19 20:19 ` [Qemu-devel] [PATCH 04/13] linux-user/alpha: Set r20 secondary return value Richard Henderson
2019-06-13 16:23   ` Laurent Vivier
2019-05-19 20:19 ` [Qemu-devel] [PATCH 05/13] target/sparc: Define an enumeration for accessing env->regwptr Richard Henderson
2019-05-19 20:19 ` [Qemu-devel] [PATCH 06/13] linux-user/sparc: Use WREG constants in sparc/target_cpu.h Richard Henderson
2019-05-19 20:19 ` [Qemu-devel] [PATCH 07/13] linux-user/sparc: Use WREG constants in sparc/signal.c Richard Henderson
2019-06-13 21:31   ` Laurent Vivier
2019-05-19 20:19 ` [Qemu-devel] [PATCH 08/13] linux-user/sparc: Fix cpu_clone_regs Richard Henderson
2019-05-19 20:19 ` [Qemu-devel] [PATCH 09/13] linux-user/sparc: Flush register windows before clone/fork/vfork Richard Henderson
2019-05-19 20:19 ` [Qemu-devel] [PATCH 10/13] scripts/qemu-binfmt-conf: Update for sparc64 Richard Henderson
2019-06-13 15:22   ` Laurent Vivier
2019-05-19 20:19 ` [Qemu-devel] [PATCH 11/13] tests/tcg/multiarch/linux-test: Fix error check for shmat Richard Henderson
2019-06-13 15:08   ` Laurent Vivier
2019-05-19 20:19 ` [Qemu-devel] [PATCH 12/13] linux-user: Fix shmat emulation by honoring host SHMLBA Richard Henderson
2019-05-22  9:40   ` Laurent Vivier
2019-05-19 20:19 ` [Qemu-devel] [PATCH 13/13] linux-user: Align mmap_find_vma to host page size Richard Henderson
2019-05-22  9:45   ` Laurent Vivier
2019-06-11 20:53 ` [Qemu-devel] [PATCH 00/13] linux-user: path, clone, sparc, shmat fixes Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.