All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Vivier <laurent@vivier.eu>
To: qemu-devel@nongnu.org
Cc: Max Filippov <jcmvbkbc@gmail.com>,
	Riku Voipio <riku.voipio@iki.fi>,
	Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PULL 09/15] target/xtensa: linux-user: add call0 ABI support
Date: Tue, 10 Sep 2019 18:35:54 +0200	[thread overview]
Message-ID: <20190910163600.19971-10-laurent@vivier.eu> (raw)
In-Reply-To: <20190910163600.19971-1-laurent@vivier.eu>

From: Max Filippov <jcmvbkbc@gmail.com>

Xtensa binaries built for call0 ABI don't rotate register window on
function calls and returns. Invocation of signal handlers from the
kernel is therefore different in windowed and call0 ABIs.
There's currently no way to determine xtensa ELF binary ABI from the
binary itself. Add handler for the -xtensa-abi-call0 command line
parameter/QEMU_XTENSA_ABI_CALL0 envitonment variable to the qemu-user
and record ABI choice. Use it to initialize PS.WOE in xtensa_cpu_reset.
Check PS.WOE in setup_rt_frame to determine how a signal should be
delivered.

Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Message-Id: <20190906165713.5558-1-jcmvbkbc@gmail.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 linux-user/main.c          | 11 +++++++++++
 linux-user/xtensa/signal.c | 25 +++++++++++++++++--------
 target/xtensa/cpu.c        | 24 ++++++++++++++++++++----
 target/xtensa/cpu.h        |  3 +++
 4 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 24cb24f0bf8f..27d9a87bc83d 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -391,6 +391,13 @@ static void handle_arg_trace(const char *arg)
     trace_file = trace_opt_parse(arg);
 }
 
+#if defined(TARGET_XTENSA)
+static void handle_arg_abi_call0(const char *arg)
+{
+    xtensa_set_abi_call0();
+}
+#endif
+
 struct qemu_argument {
     const char *argv;
     const char *env;
@@ -444,6 +451,10 @@ static const struct qemu_argument arg_table[] = {
      "",           "[[enable=]<pattern>][,events=<file>][,file=<file>]"},
     {"version",    "QEMU_VERSION",     false, handle_arg_version,
      "",           "display version information and exit"},
+#if defined(TARGET_XTENSA)
+    {"xtensa-abi-call0", "QEMU_XTENSA_ABI_CALL0", false, handle_arg_abi_call0,
+     "",           "assume CALL0 Xtensa ABI"},
+#endif
     {NULL, NULL, false, NULL, NULL, NULL}
 };
 
diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c
index 8d54ef3ae34b..590f0313ffe9 100644
--- a/linux-user/xtensa/signal.c
+++ b/linux-user/xtensa/signal.c
@@ -134,6 +134,8 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     abi_ulong frame_addr;
     struct target_rt_sigframe *frame;
     uint32_t ra;
+    bool abi_call0;
+    unsigned base;
     int i;
 
     frame_addr = get_sigframe(ka, env, sizeof(*frame));
@@ -182,20 +184,27 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
         __put_user(0x00, &frame->retcode[5]);
 #endif
     }
-    env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT);
-    if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER)) {
-        env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT);
-    }
     memset(env->regs, 0, sizeof(env->regs));
     env->pc = ka->_sa_handler;
     env->regs[1] = frame_addr;
     env->sregs[WINDOW_BASE] = 0;
     env->sregs[WINDOW_START] = 1;
 
-    env->regs[4] = (ra & 0x3fffffff) | 0x40000000;
-    env->regs[6] = sig;
-    env->regs[7] = frame_addr + offsetof(struct target_rt_sigframe, info);
-    env->regs[8] = frame_addr + offsetof(struct target_rt_sigframe, uc);
+    abi_call0 = (env->sregs[PS] & PS_WOE) == 0;
+    env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT);
+
+    if (abi_call0) {
+        base = 0;
+        env->regs[base] = ra;
+    } else {
+        env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT);
+        base = 4;
+        env->regs[base] = (ra & 0x3fffffff) | 0x40000000;
+    }
+    env->regs[base + 2] = sig;
+    env->regs[base + 3] = frame_addr + offsetof(struct target_rt_sigframe,
+                                                info);
+    env->regs[base + 4] = frame_addr + offsetof(struct target_rt_sigframe, uc);
     unlock_user_struct(frame, frame_addr, 1);
     return;
 
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 76db1741a796..c65dcf9dd782 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -53,6 +53,20 @@ static bool xtensa_cpu_has_work(CPUState *cs)
 #endif
 }
 
+#ifdef CONFIG_USER_ONLY
+static bool abi_call0;
+
+void xtensa_set_abi_call0(void)
+{
+    abi_call0 = true;
+}
+
+bool xtensa_abi_call0(void)
+{
+    return abi_call0;
+}
+#endif
+
 /* CPUClass::reset() */
 static void xtensa_cpu_reset(CPUState *s)
 {
@@ -70,10 +84,12 @@ static void xtensa_cpu_reset(CPUState *s)
             XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
     env->pending_irq_level = 0;
 #else
-    env->sregs[PS] =
-        (xtensa_option_enabled(env->config,
-                               XTENSA_OPTION_WINDOWED_REGISTER) ? PS_WOE : 0) |
-        PS_UM | (3 << PS_RING_SHIFT);
+    env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT);
+    if (xtensa_option_enabled(env->config,
+                              XTENSA_OPTION_WINDOWED_REGISTER) &&
+        !xtensa_abi_call0()) {
+        env->sregs[PS] |= PS_WOE;
+    }
 #endif
     env->sregs[VECBASE] = env->config->vecbase;
     env->sregs[IBREAKENABLE] = 0;
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 0459243e6bb1..b363ffcf1066 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -673,6 +673,9 @@ static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env)
 {
     return env->system_er;
 }
+#else
+void xtensa_set_abi_call0(void);
+bool xtensa_abi_call0(void);
 #endif
 
 static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
-- 
2.21.0



  parent reply	other threads:[~2019-09-10 16:52 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-10 16:35 [Qemu-devel] [PULL 00/15] Linux user for 4.2 patches Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 01/15] linux-user: remove useless variable Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 02/15] linux-user: Add AT_HWCAP2 for aarch64-linux-user Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 03/15] linux-user: erroneous fd_trans_unregister call Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 04/15] linux-user: fail and report on bad dfilter specs Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 05/15] linux-user: add memfd_create Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 06/15] linux-user: Pass CPUState to MAX_RESERVED_VA Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 07/15] linux-user/arm: Adjust MAX_RESERVED_VA for M-profile Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 08/15] linux-user: Support gdb 'qOffsets' query for ELF Laurent Vivier
2019-09-10 16:35 ` Laurent Vivier [this message]
2019-09-10 16:35 ` [Qemu-devel] [PULL 10/15] linux-user: drop redundant handling of environment variables Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 11/15] linux-user: Add support for RNDRESEEDCRNG ioctl Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 12/15] linux-user: Add support for FIOGETOWN and FIOSETOWN ioctls Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 13/15] linux-user: Add support for FDFLUSH ioctl Laurent Vivier
2019-09-10 16:35 ` [Qemu-devel] [PULL 14/15] linux-user: Add support for FDMSGON and FDMSGOFF ioctls Laurent Vivier
2019-09-10 16:36 ` [Qemu-devel] [PULL 15/15] linux-user: Add support for FDRESET, FDRAWCMD, FDTWADDLE, and FDEJECT ioctls Laurent Vivier
2019-09-10 20:52 ` [Qemu-devel] [PULL 00/15] Linux user for 4.2 patches no-reply
2019-09-11  0:38 ` no-reply
2019-09-11  2:32 ` no-reply
2019-09-11  4:36 ` no-reply
2019-09-11  6:36   ` Laurent Vivier
2019-09-11  6:45 ` no-reply
2019-09-11  7:37 ` no-reply
2019-09-11  8:40 ` no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190910163600.19971-10-laurent@vivier.eu \
    --to=laurent@vivier.eu \
    --cc=jcmvbkbc@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=riku.voipio@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.