qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 3/3] linux-user:Signal handling for MIPS64
@ 2011-04-29  6:20 Khansa Butt
  0 siblings, 0 replies; 7+ messages in thread
From: Khansa Butt @ 2011-04-29  6:20 UTC (permalink / raw)
  To: Riku Voipio, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 13287 bytes --]

>From 1ab1973118d9e676fcaaf234d153c8c7056aa82a Mon Sep 17 00:00:00 2001
From: Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt <
khansa@kics.edu.pk>
Date: Fri, 29 Apr 2011 10:52:38 +0500
Subject: [PATCH 3/3] linux-user:Signal handling for MIPS64


Signed-off-by: Khansa Butt <khansa@kics.edu.pk>
---
 linux-user/signal.c       |  331
+++++++++++++++++++++++++++++++++++++++++++--
 linux-user/syscall_defs.h |    4 +
 2 files changed, 325 insertions(+), 10 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 66786db..e387a5b 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -221,7 +221,11 @@ static inline void
host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
         /* XXX: potential problem if 64 bit */
         tinfo->_sifields._rt._sigval.sival_ptr =
             (abi_ulong)(unsigned long)info->si_value.sival_ptr;
+    } else {
+        tinfo->_sifields._kill._pid = info->si_pid;
+        tinfo->_sifields._kill._uid = info->si_uid;
     }
+
 }

 static void tswap_siginfo(target_siginfo_t *tinfo,
@@ -243,6 +247,9 @@ static void tswap_siginfo(target_siginfo_t *tinfo,
         tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
         tinfo->_sifields._rt._sigval.sival_ptr =
             tswapl(info->_sifields._rt._sigval.sival_ptr);
+    } else {
+        tinfo->_sifields._kill._pid = tswap32(info->_sifields._kill._pid);
+        tinfo->_sifields._kill._uid = tswap32(info->_sifields._kill._uid);
     }
 }

@@ -2413,28 +2420,332 @@ void sparc64_get_context(CPUSPARCState *env)
 #endif
 #elif defined(TARGET_ABI_MIPSN64)

-static void setup_frame(int sig, struct target_sigaction *ka,
- target_sigset_t *set, CPUState *env)
+struct target_sigcontext {
+    uint32_t   sc_regmask;     /* Unused */
+    uint32_t   sc_status;
+    uint64_t   sc_pc;
+    uint64_t   sc_regs[32];
+    uint64_t   sc_fpregs[32];
+    uint32_t   sc_ownedfp;     /* Unused */
+    uint32_t   sc_fpc_csr;
+    uint32_t   sc_fpc_eir;     /* Unused */
+    uint32_t   sc_used_math;
+    uint32_t   sc_dsp;         /* dsp status, was sc_ssflags */
+    uint32_t   pad0;
+    uint64_t   sc_mdhi;
+    uint64_t   sc_mdlo;
+    target_ulong   sc_hi1;         /* Was sc_cause */
+    target_ulong   sc_lo1;         /* Was sc_badvaddr */
+    target_ulong   sc_hi2;         /* Was sc_sigset[4] */
+    target_ulong   sc_lo2;
+    target_ulong   sc_hi3;
+    target_ulong   sc_lo3;
+};
+
+struct target_ucontext {
+    target_ulong tuc_flags;
+    target_ulong tuc_link;
+    target_stack_t tuc_stack;
+    struct target_sigcontext tuc_mcontext;
+    target_sigset_t tuc_sigmask;
+};
+
+struct target_rt_sigframe {
+    uint64_t rs_ass[8];               /* argument save space for n64 */
+    uint32_t rs_code[2];              /* signal trampoline */
+    struct target_siginfo rs_info;
+    struct target_ucontext rs_uc;
+};
+
+/* Install trampoline to jump back from signal handler */
+static inline int install_sigtramp(unsigned int *tramp,   unsigned int
syscall)
 {
-    fprintf(stderr, "setup_frame: not implemented\n");
+    int err;
+
+    /*
+    * Set up the return code ...
+    *
+    *         li      v0, __NR__foo_sigreturn
+    *         syscall
+    */
+
+    err = __put_user(0x24020000 + syscall, tramp + 0);
+    err |= __put_user(0x0000000c          , tramp + 1);
+    /* flush_cache_sigtramp((unsigned long) tramp); */
+    return err;
+}
+
+static inline int
+setup_sigcontext(CPUState *regs, struct target_sigcontext *sc)
+{
+    int err = 0;
+
+    err |= __put_user(regs->active_tc.PC, &sc->sc_pc);
+
+#define save_gp_reg(i) do {                         \
+        err |= __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]); \
+    } while (0)
+    __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+    save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+    save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+    save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+    save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+    save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+    save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+    save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+    save_gp_reg(31);
+#undef save_gp_reg
+
+    err |= __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
+    err |= __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
+
+    /* Not used yet, but might be useful if we ever have DSP suppport */
+#if 0
+    if (cpu_has_dsp) {
+    err |= __put_user(mfhi1(), &sc->sc_hi1);
+    err |= __put_user(mflo1(), &sc->sc_lo1);
+    err |= __put_user(mfhi2(), &sc->sc_hi2);
+    err |= __put_user(mflo2(), &sc->sc_lo2);
+    err |= __put_user(mfhi3(), &sc->sc_hi3);
+    err |= __put_user(mflo3(), &sc->sc_lo3);
+    err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+    }
+    /* same with 64 bit */
+#ifdef CONFIG_64BIT
+    err |= __put_user(regs->hi, &sc->sc_hi[0]);
+    err |= __put_user(regs->lo, &sc->sc_lo[0]);
+    if (cpu_has_dsp) {
+    err |= __put_user(mfhi1(), &sc->sc_hi[1]);
+    err |= __put_user(mflo1(), &sc->sc_lo[1]);
+    err |= __put_user(mfhi2(), &sc->sc_hi[2]);
+    err |= __put_user(mflo2(), &sc->sc_lo[2]);
+    err |= __put_user(mfhi3(), &sc->sc_hi[3]);
+    err |= __put_user(mflo3(), &sc->sc_lo[3]);
+    err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+    }
+#endif
+#endif
+
+#if 0
+    err |= __put_user(!!used_math(), &sc->sc_used_math);
+
+    if (!used_math())
+    goto out;
+
+    /*
+    * Save FPU state to signal context.  Signal handler will "inherit"
+    * current FPU state.
+    */
+    preempt_disable();
+
+    if (!is_fpu_owner()) {
+    own_fpu();
+    restore_fp(current);
+    }
+    err |= save_fp_context(sc);
+
+    preempt_enable();
+    out:
+#endif
+    return err;
+}
+
+static inline int
+restore_sigcontext(CPUState *regs, struct target_sigcontext *sc)
+{
+    int err = 0;
+
+    err |= __get_user(regs->CP0_EPC, &sc->sc_pc);
+
+    err |= __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
+    err |= __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
+
+#define restore_gp_reg(i) do {                              \
+        err |= __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);     \
+    } while (0)
+    restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+    restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+    restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+    restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+    restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+    restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+    restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+    restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+    restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+    restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+    restore_gp_reg(31);
+#undef restore_gp_reg
+
+#if 0
+    if (cpu_has_dsp) {
+    err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
+    err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
+    err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
+    err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
+    err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
+    err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
+    err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+    }
+#ifdef CONFIG_64BIT
+    err |= __get_user(regs->hi, &sc->sc_hi[0]);
+    err |= __get_user(regs->lo, &sc->sc_lo[0]);
+    if (cpu_has_dsp) {
+    err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
+    err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
+    err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
+    err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
+    err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
+    err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
+    err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+    }
+#endif
+
+    err |= __get_user(used_math, &sc->sc_used_math);
+    conditional_used_math(used_math);
+
+    preempt_disable();
+
+    if (used_math()) {
+    /* restore fpu context if we have used it before */
+    own_fpu();
+    err |= restore_fp_context(sc);
+    } else {
+    /* signal handler may have used FPU.  Give it up. */
+    lose_fpu();
+    }
+
+    preempt_enable();
+#endif
+    return err;
+}
+/*
+ * Determine which stack to use..
+ */
+static inline abi_ulong
+get_sigframe(struct target_sigaction *ka, CPUState *regs, size_t
frame_size)
+{
+    unsigned long sp;
+
+    /* Default to using normal stack */
+    sp = regs->active_tc.gpr[29];
+
+    /*
+     * FPU emulator may have it's own trampoline active just
+     * above the user stack, 16-bytes before the next lowest
+     * 16 byte boundary.  Try to avoid trashing it.
+     */
+    sp -= 32;
+
+    /* This is the X/Open sanctioned signal stack switching.  */
+    if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
+        sp = target_sigaltstack_used.ss_sp +
target_sigaltstack_used.ss_size;
+    }
+
+    return (sp - frame_size) & ~7;
 }

 static void setup_rt_frame(int sig, struct target_sigaction *ka,
                            target_siginfo_t *info,
-   target_sigset_t *set, CPUState *env)
+               target_sigset_t *set, CPUState *env)
 {
-    fprintf(stderr, "setup_rt_frame: not implemented\n");
+    struct target_rt_sigframe *frame;
+    abi_ulong frame_addr;
+    int i;
+
+    frame_addr = get_sigframe(ka, env, sizeof(*frame));
+    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))
+    goto give_sigsegv;
+
+    install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
+
+    copy_siginfo_to_user(&frame->rs_info, info);
+
+    __put_user(0, &frame->rs_uc.tuc_flags);
+    __put_user(0, &frame->rs_uc.tuc_link);
+    __put_user(target_sigaltstack_used.ss_sp,
&frame->rs_uc.tuc_stack.ss_sp);
+    __put_user(target_sigaltstack_used.ss_size,
&frame->rs_uc.tuc_stack.ss_size);
+    __put_user(sas_ss_flags(get_sp_from_cpustate(env)),
+               &frame->rs_uc.tuc_stack.ss_flags);
+
+    setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
+
+    for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+        __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
+    }
+
+    /*
+    * Arguments to signal handler:
+    *
+    *   a0 = signal number
+    *   a1 = pointer to struct siginfo
+    *   a2 = pointer to struct ucontext
+    *
+    * $25 and PC point to the signal handler, $29 points to the
+    * struct sigframe.
+    */
+    env->active_tc.gpr[ 4] = sig;
+    env->active_tc.gpr[ 5] = frame_addr
+                             + offsetof(struct target_rt_sigframe,
rs_info);
+    env->active_tc.gpr[ 6] = frame_addr
+                             + offsetof(struct target_rt_sigframe, rs_uc);
+    env->active_tc.gpr[29] = frame_addr;
+    env->active_tc.gpr[31] = frame_addr
+                             + offsetof(struct target_rt_sigframe,
rs_code);
+    /* The original kernel code sets CP0_EPC to the handler
+    * since it returns to userland using eret
+    * we cannot do this here, and we must set PC directly */
+    env->active_tc.PC = env->active_tc.gpr[25] = ka->_sa_handler;
+    unlock_user_struct(frame, frame_addr, 1);
+    return;
+
+give_sigsegv:
+    unlock_user_struct(frame, frame_addr, 1);
+    force_sig(TARGET_SIGSEGV/*, current*/);
+    return;
 }

-long do_sigreturn(CPUState *env)
+long do_rt_sigreturn(CPUState *env)
 {
-    fprintf(stderr, "do_sigreturn: not implemented\n");
-    return -TARGET_ENOSYS;
+    struct target_rt_sigframe *frame;
+    abi_ulong frame_addr;
+    sigset_t blocked;
+
+#if defined(DEBUG_SIGNAL)
+    fprintf(stderr, "do_rt_sigreturn\n");
+#endif
+    frame_addr = env->active_tc.gpr[29];
+    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
+    goto badframe;
+
+    target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
+    sigprocmask(SIG_SETMASK, &blocked, NULL);
+
+    if (restore_sigcontext(env, &frame->rs_uc.tuc_mcontext))
+        goto badframe;
+
+    if (do_sigaltstack(frame_addr +
+               offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
+               0, get_sp_from_cpustate(env)) == -EFAULT)
+        goto badframe;
+
+    env->active_tc.PC = env->CP0_EPC;
+    env->CP0_EPC = 0;
+    return -TARGET_QEMU_ESIGRETURN;
+
+badframe:
+    force_sig(TARGET_SIGSEGV/*, current*/);
+    return 0;
 }

-long do_rt_sigreturn(CPUState *env)
+static void setup_frame(int sig, struct target_sigaction *ka,
+            target_sigset_t *set, CPUState *env)
 {
-    fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+    fprintf(stderr, "setup_frame: not implemented\n");
+}
+
+long do_sigreturn(CPUState *env)
+{
+    fprintf(stderr, "do_sigreturn: not implemented\n");
     return -TARGET_ENOSYS;
 }

diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index bde8921..50a8599 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -506,7 +506,11 @@ struct target_sigaction {
 };
 #elif defined(TARGET_MIPS)
 struct target_sigaction {
+#if defined(TARGET_ABI_MIPSN64)
+    abi_ulong sa_flags;
+#else
  uint32_t sa_flags;
+#endif
 #if defined(TARGET_ABI_MIPSN32)
  uint32_t _sa_handler;
 #else
-- 
1.7.3.4

[-- Attachment #2: Type: text/html, Size: 18509 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 0/3] MIPS64 user mode emulation in QEMU with Cavium specific instruction support
@ 2011-11-30 11:07 khansa
  2011-11-30 11:07 ` [Qemu-devel] [PATCH 3/3] linux-user:Signal handling for MIPS64 khansa
  0 siblings, 1 reply; 7+ messages in thread
From: khansa @ 2011-11-30 11:07 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, riku.voipio, Khansa Butt, aurelien

From: Khansa Butt <khansa@kics.edu.pk>

This is the team work of Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt
from HPCN Lab KICS UET Lahore.

 configure                             |    1 +
 default-configs/mips64-linux-user.mak |    1 +
 linux-user/main.c                     |   21 ++-
 linux-user/mips64/syscall.h           |    2 +
 linux-user/signal.c                   |  429 ++++++++++++++++++++++++++++++++-
 target-mips/translate.c               |    4 +
 6 files changed, 444 insertions(+), 14 deletions(-)
 create mode 100644 default-configs/mips64-linux-user.mak

-- 
1.7.3.4

^ permalink raw reply	[flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 0/3] MIPS64 user mode emulation in QEMU
@ 2011-12-08  5:25 khansa
  2011-12-08  5:25 ` [Qemu-devel] [PATCH 3/3] linux-user:Signal handling for MIPS64 khansa
  0 siblings, 1 reply; 7+ messages in thread
From: khansa @ 2011-12-08  5:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, riku.voipio, Khansa Butt, aurelien

From: Khansa Butt <khansa@kics.edu.pk>

This is the team work of Ehsan-ul-Haq, Abdul Qadeer, Abdul Waheed, Khansa Butt
from HPCN Lab KICS UET Lahore.
In previous patch set we were including Cavium specific instructions along with 
Cavium specifc registers in UME. Because of these register fields we had to bump
the cpu version up but I noticed that cpu_save() and cpu_load() are not called in
UME so we decided to postpone Octeon specific changes ( registers and instructions)
and will include them in our SME work( we are currently working on system mode 
emulation of Octeon board) so we closing the following thread
http://lists.gnu.org/archive/html/qemu-devel/2011-10/msg02665.html
Please review this new patch set which is without cavium instruction support. 

 configure                             |    1 +
 default-configs/mips64-linux-user.mak |    1 +
 linux-user/main.c                     |   21 ++-
 linux-user/mips64/syscall.h           |    2 +
 linux-user/signal.c                   |  429 ++++++++++++++++++++++++++++++++-
 target-mips/translate.c               |    4 +
 6 files changed, 444 insertions(+), 14 deletions(-)
 create mode 100644 default-configs/mips64-linux-user.mak

-- 
1.7.3.4

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

end of thread, other threads:[~2011-12-29 11:24 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-29  6:20 [Qemu-devel] [PATCH 3/3] linux-user:Signal handling for MIPS64 Khansa Butt
  -- strict thread matches above, loose matches on Subject: below --
2011-11-30 11:07 [Qemu-devel] [PATCH 0/3] MIPS64 user mode emulation in QEMU with Cavium specific instruction support khansa
2011-11-30 11:07 ` [Qemu-devel] [PATCH 3/3] linux-user:Signal handling for MIPS64 khansa
2011-12-08  5:25 [Qemu-devel] [PATCH 0/3] MIPS64 user mode emulation in QEMU khansa
2011-12-08  5:25 ` [Qemu-devel] [PATCH 3/3] linux-user:Signal handling for MIPS64 khansa
2011-12-14 16:20   ` Richard Henderson
2011-12-28 11:09     ` Khansa Butt
2011-12-29 10:58     ` Khansa Butt
2011-12-29 11:23       ` Andreas Färber

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).