From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: gang.chen.5i5j@gmail.com
Subject: [Qemu-devel] [PATCH 10/14] linux-user/tilegx: Implement tilegx signal features
Date: Thu, 1 Oct 2015 12:38:42 +1000 [thread overview]
Message-ID: <1443667126-6257-11-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1443667126-6257-1-git-send-email-rth@twiddle.net>
From: Chen Gang <gang.chen.5i5j@gmail.com>
[rth: Remove the spreg[EX1] handling, as it's irrelevant to user-mode.]
Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
Message-Id: <1443312618-13641-1-git-send-email-gang.chen.5i5j@gmail.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
linux-user/signal.c | 160 +++++++++++++++++++++++++++++++++++++++++++-
linux-user/tilegx/syscall.h | 3 +
2 files changed, 162 insertions(+), 1 deletion(-)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 502efd9..a84e9cd 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -5543,6 +5543,163 @@ long do_rt_sigreturn(CPUAlphaState *env)
force_sig(TARGET_SIGSEGV);
}
+#elif defined(TARGET_TILEGX)
+
+struct target_sigcontext {
+ union {
+ /* General-purpose registers. */
+ abi_ulong gregs[56];
+ struct {
+ abi_ulong __gregs[53];
+ abi_ulong tp; /* Aliases gregs[TREG_TP]. */
+ abi_ulong sp; /* Aliases gregs[TREG_SP]. */
+ abi_ulong lr; /* Aliases gregs[TREG_LR]. */
+ };
+ };
+ abi_ulong pc; /* Program counter. */
+ abi_ulong ics; /* In Interrupt Critical Section? */
+ abi_ulong faultnum; /* Fault number. */
+ abi_ulong pad[5];
+};
+
+struct target_ucontext {
+ abi_ulong tuc_flags;
+ abi_ulong tuc_link;
+ target_stack_t tuc_stack;
+ struct target_sigcontext tuc_mcontext;
+ target_sigset_t tuc_sigmask; /* mask last for extensibility */
+};
+
+struct target_rt_sigframe {
+ unsigned char save_area[16]; /* caller save area */
+ struct target_siginfo info;
+ struct target_ucontext uc;
+};
+
+static void setup_sigcontext(struct target_sigcontext *sc,
+ CPUArchState *env, int signo)
+{
+ int i;
+
+ for (i = 0; i < TILEGX_R_COUNT; ++i) {
+ __put_user(env->regs[i], &sc->gregs[i]);
+ }
+
+ __put_user(env->pc, &sc->pc);
+ __put_user(0, &sc->ics);
+ __put_user(signo, &sc->faultnum);
+}
+
+static void restore_sigcontext(CPUTLGState *env, struct target_sigcontext *sc)
+{
+ int i;
+
+ for (i = 0; i < TILEGX_R_COUNT; ++i) {
+ __get_user(env->regs[i], &sc->gregs[i]);
+ }
+
+ __get_user(env->pc, &sc->pc);
+}
+
+static abi_ulong get_sigframe(struct target_sigaction *ka, CPUArchState *env,
+ size_t frame_size)
+{
+ unsigned long sp = env->regs[TILEGX_R_SP];
+
+ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) {
+ return -1UL;
+ }
+
+ if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
+ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+ }
+
+ sp -= frame_size;
+ sp &= -16UL;
+ return sp;
+}
+
+static void setup_rt_frame(int sig, struct target_sigaction *ka,
+ target_siginfo_t *info,
+ target_sigset_t *set, CPUArchState *env)
+{
+ abi_ulong frame_addr;
+ struct target_rt_sigframe *frame;
+ unsigned long restorer;
+
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+ goto give_sigsegv;
+ }
+
+ /* Always write at least the signal number for the stack backtracer. */
+ if (ka->sa_flags & TARGET_SA_SIGINFO) {
+ /* At sigreturn time, restore the callee-save registers too. */
+ tswap_siginfo(&frame->info, info);
+ /* regs->flags |= PT_FLAGS_RESTORE_REGS; FIXME: we can skip it? */
+ } else {
+ __put_user(info->si_signo, &frame->info.si_signo);
+ }
+
+ /* Create the ucontext. */
+ __put_user(0, &frame->uc.tuc_flags);
+ __put_user(0, &frame->uc.tuc_link);
+ __put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
+ __put_user(sas_ss_flags(env->regs[TILEGX_R_SP]),
+ &frame->uc.tuc_stack.ss_flags);
+ __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
+ setup_sigcontext(&frame->uc.tuc_mcontext, env, info->si_signo);
+
+ restorer = (unsigned long) do_rt_sigreturn;
+ if (ka->sa_flags & TARGET_SA_RESTORER) {
+ restorer = (unsigned long) ka->sa_restorer;
+ }
+ env->pc = (unsigned long) ka->_sa_handler;
+ env->regs[TILEGX_R_SP] = (unsigned long) frame;
+ env->regs[TILEGX_R_LR] = restorer;
+ env->regs[0] = (unsigned long) sig;
+ env->regs[1] = (unsigned long) &frame->info;
+ env->regs[2] = (unsigned long) &frame->uc;
+ /* regs->flags |= PT_FLAGS_CALLER_SAVES; FIXME: we can skip it? */
+
+ unlock_user_struct(frame, frame_addr, 1);
+ return;
+
+give_sigsegv:
+ if (sig == TARGET_SIGSEGV) {
+ ka->_sa_handler = TARGET_SIG_DFL;
+ }
+ force_sig(TARGET_SIGSEGV /* , current */);
+}
+
+long do_rt_sigreturn(CPUTLGState *env)
+{
+ abi_ulong frame_addr = env->regs[TILEGX_R_SP];
+ struct target_rt_sigframe *frame;
+ sigset_t set;
+
+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
+ goto badframe;
+ }
+ target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
+ do_sigprocmask(SIG_SETMASK, &set, NULL);
+
+ restore_sigcontext(env, &frame->uc.tuc_mcontext);
+ if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
+ uc.tuc_stack),
+ 0, env->regs[TILEGX_R_SP]) == -EFAULT) {
+ goto badframe;
+ }
+
+ unlock_user_struct(frame, frame_addr, 0);
+ return env->regs[TILEGX_R_RE];
+
+
+ badframe:
+ unlock_user_struct(frame, frame_addr, 0);
+ force_sig(TARGET_SIGSEGV);
+}
+
#else
static void setup_frame(int sig, struct target_sigaction *ka,
@@ -5662,7 +5819,8 @@ void process_pending_signals(CPUArchState *cpu_env)
}
#endif
/* prepare the stack frame of the virtual CPU */
-#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
+#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) \
+ || defined(TARGET_TILEGX)
/* These targets do not have traditional signals. */
setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);
#else
diff --git a/linux-user/tilegx/syscall.h b/linux-user/tilegx/syscall.h
index 653ece1..a938d4e 100644
--- a/linux-user/tilegx/syscall.h
+++ b/linux-user/tilegx/syscall.h
@@ -37,4 +37,7 @@ struct target_pt_regs {
#define TARGET_MLOCKALL_MCL_CURRENT 1
#define TARGET_MLOCKALL_MCL_FUTURE 2
+/* For faultnum */
+#define TARGET_INT_SWINT_1 14
+
#endif
--
2.4.3
next prev parent reply other threads:[~2015-10-01 2:40 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-01 2:38 [Qemu-devel] [PATCH 00/14] Collected tilegx patches Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 01/14] target-tilegx: Use V1 in simd_helper.c Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 02/14] target-tilegx: Implement v*shl, v*shru, and v*shrs instructions Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 03/14] target-tilegx: Implement v*add and v*sub instructions Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 04/14] target-tilegx: Implement v1multu instruction Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 05/14] target-tilegx: Implement crc instructions Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 06/14] target-tilegx: Implement table index instructions Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 07/14] target-tilegx: Implement complex multiply instructions Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 08/14] target-tilegx: Let x1 pipe process bpt instruction only Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 09/14] linux-user/syscall_defs.h: Sync the latest si_code from Linux kernel Richard Henderson
2015-10-01 2:38 ` Richard Henderson [this message]
2015-10-01 2:38 ` [Qemu-devel] [PATCH 11/14] target-tilegx: Decode ill pseudo-instructions Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 12/14] target-tilegx: Use TILEGX_EXCP_SIGNAL instead of TILEGX_EXCP_SEGV Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 13/14] target-tilegx: Fix a typo for mnemonic about "ld_add" Richard Henderson
2015-10-01 2:38 ` [Qemu-devel] [PATCH 14/14] target-tilegx: Handle nofault prefetch instructions Richard Henderson
[not found] ` <560D3DC0.7010500@hotmail.com>
2015-10-01 14:04 ` [Qemu-devel] [PATCH 00/14] Collected tilegx patches Chen Gang
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=1443667126-6257-11-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=gang.chen.5i5j@gmail.com \
--cc=qemu-devel@nongnu.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).