All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
To: Laurent Vivier <laurent@vivier.eu>, qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Cornelia Huck <cohuck@redhat.com>,
	Riku Voipio <riku.voipio@iki.fi>,
	qemu-s390x@nongnu.org
Subject: Re: [Qemu-devel] [PATCH for 2.13 v2 18/20] linux-user: move mips/mips64 signal.c parts to mips directory
Date: Fri, 23 Mar 2018 21:57:20 -0300	[thread overview]
Message-ID: <94189782-743d-12a1-f992-1aa60cb9113c@amsat.org> (raw)
In-Reply-To: <20180323225739.17329-19-laurent@vivier.eu>

On 03/23/2018 07:57 PM, Laurent Vivier wrote:
> No code change, only move code from signal.c to
> mips/signal.c, except adding includes and
> exporting setup_frame() and setup_rt_frame().
> 
> mips64/signal.c includes mips/signal.c
> 
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  linux-user/mips/signal.c          | 382 ++++++++++++++++++++++++++++++++++++++
>  linux-user/mips/target_signal.h   |   9 +-
>  linux-user/mips64/signal.c        |   2 +
>  linux-user/mips64/target_signal.h |   4 +-
>  linux-user/signal.c               | 381 +------------------------------------
>  5 files changed, 396 insertions(+), 382 deletions(-)
> 
> diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
> index 02ca338b6c..a44e5b59e9 100644
> --- a/linux-user/mips/signal.c
> +++ b/linux-user/mips/signal.c
> @@ -16,3 +16,385 @@
>   *  You should have received a copy of the GNU General Public License
>   *  along with this program; if not, see <http://www.gnu.org/licenses/>.
>   */
> +#include "qemu/osdep.h"
> +#include "qemu.h"
> +#include "target_signal.h"
> +#include "signal-common.h"
> +#include "linux-user/trace.h"
> +
> +# if defined(TARGET_ABI_MIPSO32)
> +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;
> +};
> +# else /* N32 || N64 */
> +struct target_sigcontext {
> +    uint64_t sc_regs[32];
> +    uint64_t sc_fpregs[32];
> +    uint64_t sc_mdhi;
> +    uint64_t sc_hi1;
> +    uint64_t sc_hi2;
> +    uint64_t sc_hi3;
> +    uint64_t sc_mdlo;
> +    uint64_t sc_lo1;
> +    uint64_t sc_lo2;
> +    uint64_t sc_lo3;
> +    uint64_t sc_pc;
> +    uint32_t sc_fpc_csr;
> +    uint32_t sc_used_math;
> +    uint32_t sc_dsp;
> +    uint32_t sc_reserved;
> +};
> +# endif /* O32 */
> +
> +struct sigframe {
> +    uint32_t sf_ass[4];			/* argument save space for o32 */
> +    uint32_t sf_code[2];			/* signal trampoline */
> +    struct target_sigcontext sf_sc;
> +    target_sigset_t sf_mask;
> +};
> +
> +struct target_ucontext {
> +    target_ulong tuc_flags;
> +    target_ulong tuc_link;
> +    target_stack_t tuc_stack;
> +    target_ulong pad0;
> +    struct target_sigcontext tuc_mcontext;
> +    target_sigset_t tuc_sigmask;
> +};
> +
> +struct target_rt_sigframe {
> +    uint32_t rs_ass[4];               /* argument save space for o32 */
> +    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)
> +{
> +    int err = 0;
> +
> +    /*
> +     * Set up the return code ...
> +     *
> +     *         li      v0, __NR__foo_sigreturn
> +     *         syscall
> +     */
> +
> +    __put_user(0x24020000 + syscall, tramp + 0);
> +    __put_user(0x0000000c          , tramp + 1);
> +    return err;
> +}
> +
> +static inline void setup_sigcontext(CPUMIPSState *regs,
> +                                    struct target_sigcontext *sc)
> +{
> +    int i;
> +
> +    __put_user(exception_resume_pc(regs), &sc->sc_pc);
> +    regs->hflags &= ~MIPS_HFLAG_BMASK;
> +
> +    __put_user(0, &sc->sc_regs[0]);
> +    for (i = 1; i < 32; ++i) {
> +        __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
> +    }
> +
> +    __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
> +    __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
> +
> +    /* Rather than checking for dsp existence, always copy.  The storage
> +       would just be garbage otherwise.  */
> +    __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
> +    __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
> +    __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
> +    __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
> +    __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
> +    __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
> +    {
> +        uint32_t dsp = cpu_rddsp(0x3ff, regs);
> +        __put_user(dsp, &sc->sc_dsp);
> +    }
> +
> +    __put_user(1, &sc->sc_used_math);
> +
> +    for (i = 0; i < 32; ++i) {
> +        __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
> +    }
> +}
> +
> +static inline void
> +restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
> +{
> +    int i;
> +
> +    __get_user(regs->CP0_EPC, &sc->sc_pc);
> +
> +    __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
> +    __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
> +
> +    for (i = 1; i < 32; ++i) {
> +        __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
> +    }
> +
> +    __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
> +    __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
> +    __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
> +    __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
> +    __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
> +    __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
> +    {
> +        uint32_t dsp;
> +        __get_user(dsp, &sc->sc_dsp);
> +        cpu_wrdsp(dsp, 0x3ff, regs);
> +    }
> +
> +    for (i = 0; i < 32; ++i) {
> +        __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
> +    }
> +}
> +
> +/*
> + * Determine which stack to use..
> + */
> +static inline abi_ulong
> +get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
> +{
> +    unsigned long sp;
> +
> +    /* Default to using normal stack */
> +    sp = regs->active_tc.gpr[29];
> +
> +    /*
> +     * FPU emulator may have its 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 mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
> +{
> +    if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
> +        env->hflags &= ~MIPS_HFLAG_M16;
> +        env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
> +        env->active_tc.PC &= ~(target_ulong) 1;
> +    }
> +}
> +
> +# if defined(TARGET_ABI_MIPSO32)
> +/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
> +void setup_frame(int sig, struct target_sigaction * ka,
> +                 target_sigset_t *set, CPUMIPSState *regs)
> +{
> +    struct sigframe *frame;
> +    abi_ulong frame_addr;
> +    int i;
> +
> +    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
> +    trace_user_setup_frame(regs, frame_addr);
> +    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
> +        goto give_sigsegv;
> +    }
> +
> +    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
> +
> +    setup_sigcontext(regs, &frame->sf_sc);
> +
> +    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
> +        __put_user(set->sig[i], &frame->sf_mask.sig[i]);
> +    }
> +
> +    /*
> +    * Arguments to signal handler:
> +    *
> +    *   a0 = signal number
> +    *   a1 = 0 (should be cause)
> +    *   a2 = pointer to struct sigcontext
> +    *
> +    * $25 and PC point to the signal handler, $29 points to the
> +    * struct sigframe.
> +    */
> +    regs->active_tc.gpr[ 4] = sig;
> +    regs->active_tc.gpr[ 5] = 0;
> +    regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
> +    regs->active_tc.gpr[29] = frame_addr;
> +    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_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 */
> +    regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
> +    mips_set_hflags_isa_mode_from_pc(regs);
> +    unlock_user_struct(frame, frame_addr, 1);
> +    return;
> +
> +give_sigsegv:
> +    force_sigsegv(sig);
> +}
> +
> +long do_sigreturn(CPUMIPSState *regs)
> +{
> +    struct sigframe *frame;
> +    abi_ulong frame_addr;
> +    sigset_t blocked;
> +    target_sigset_t target_set;
> +    int i;
> +
> +    frame_addr = regs->active_tc.gpr[29];
> +    trace_user_do_sigreturn(regs, frame_addr);
> +    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
> +        goto badframe;
> +
> +    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
> +        __get_user(target_set.sig[i], &frame->sf_mask.sig[i]);
> +    }
> +
> +    target_to_host_sigset_internal(&blocked, &target_set);
> +    set_sigmask(&blocked);
> +
> +    restore_sigcontext(regs, &frame->sf_sc);
> +
> +#if 0
> +    /*
> +     * Don't let your children do this ...
> +     */
> +    __asm__ __volatile__(
> +   	"move\t$29, %0\n\t"
> +   	"j\tsyscall_exit"
> +   	:/* no outputs */
> +   	:"r" (&regs));
> +    /* Unreached */
> +#endif
> +
> +    regs->active_tc.PC = regs->CP0_EPC;
> +    mips_set_hflags_isa_mode_from_pc(regs);
> +    /* I am not sure this is right, but it seems to work
> +    * maybe a problem with nested signals ? */
> +    regs->CP0_EPC = 0;
> +    return -TARGET_QEMU_ESIGRETURN;
> +
> +badframe:
> +    force_sig(TARGET_SIGSEGV);
> +    return -TARGET_QEMU_ESIGRETURN;
> +}
> +# endif /* O32 */
> +
> +void setup_rt_frame(int sig, struct target_sigaction *ka,
> +                    target_siginfo_t *info,
> +                    target_sigset_t *set, CPUMIPSState *env)
> +{
> +    struct target_rt_sigframe *frame;
> +    abi_ulong frame_addr;
> +    int i;
> +
> +    frame_addr = get_sigframe(ka, env, sizeof(*frame));
> +    trace_user_setup_rt_frame(env, frame_addr);
> +    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
> +        goto give_sigsegv;
> +    }
> +
> +    install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
> +
> +    tswap_siginfo(&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 siginfo_t
> +    *   a2 = pointer to ucontext_t
> +    *
> +    * $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;
> +    mips_set_hflags_isa_mode_from_pc(env);
> +    unlock_user_struct(frame, frame_addr, 1);
> +    return;
> +
> +give_sigsegv:
> +    unlock_user_struct(frame, frame_addr, 1);
> +    force_sigsegv(sig);
> +}
> +
> +long do_rt_sigreturn(CPUMIPSState *env)
> +{
> +    struct target_rt_sigframe *frame;
> +    abi_ulong frame_addr;
> +    sigset_t blocked;
> +
> +    frame_addr = env->active_tc.gpr[29];
> +    trace_user_do_rt_sigreturn(env, frame_addr);
> +    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
> +        goto badframe;
> +    }
> +
> +    target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
> +    set_sigmask(&blocked);
> +
> +    restore_sigcontext(env, &frame->rs_uc.tuc_mcontext);
> +
> +    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;
> +    mips_set_hflags_isa_mode_from_pc(env);
> +    /* I am not sure this is right, but it seems to work
> +    * maybe a problem with nested signals ? */
> +    env->CP0_EPC = 0;
> +    return -TARGET_QEMU_ESIGRETURN;
> +
> +badframe:
> +    force_sig(TARGET_SIGSEGV);
> +    return -TARGET_QEMU_ESIGRETURN;
> +}
> diff --git a/linux-user/mips/target_signal.h b/linux-user/mips/target_signal.h
> index 8dd27cef35..22ab3e4a94 100644
> --- a/linux-user/mips/target_signal.h
> +++ b/linux-user/mips/target_signal.h
> @@ -26,5 +26,12 @@ static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state)
>      return state->active_tc.gpr[29];
>  }
>  
> -
> +# if defined(TARGET_ABI_MIPSO32)
> +/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
> +void setup_frame(int sig, struct target_sigaction * ka,
> +                 target_sigset_t *set, CPUMIPSState *regs);
> +#endif
> +void setup_rt_frame(int sig, struct target_sigaction *ka,
> +                    target_siginfo_t *info,
> +                    target_sigset_t *set, CPUMIPSState *env);
>  #endif /* MIPS_TARGET_SIGNAL_H */
> diff --git a/linux-user/mips64/signal.c b/linux-user/mips64/signal.c
> index 02ca338b6c..4ed0ed90b3 100644
> --- a/linux-user/mips64/signal.c
> +++ b/linux-user/mips64/signal.c
> @@ -16,3 +16,5 @@
>   *  You should have received a copy of the GNU General Public License
>   *  along with this program; if not, see <http://www.gnu.org/licenses/>.
>   */
> +#define MIPS_TARGET_SIGNAL_H /* to only include mips64/target_signal.h */
> +#include "../mips/signal.c"
> diff --git a/linux-user/mips64/target_signal.h b/linux-user/mips64/target_signal.h
> index 67ef5a18f4..70dfe40978 100644
> --- a/linux-user/mips64/target_signal.h
> +++ b/linux-user/mips64/target_signal.h
> @@ -26,5 +26,7 @@ static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state)
>      return state->active_tc.gpr[29];
>  }
>  
> -
> +void setup_rt_frame(int sig, struct target_sigaction *ka,
> +                    target_siginfo_t *info,
> +                    target_sigset_t *set, CPUMIPSState *env);
>  #endif /* MIPS64_TARGET_SIGNAL_H */
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 2bcb32a7ce..92d7347b14 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -803,386 +803,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
>      return ret;
>  }
>  
> -#if defined(TARGET_MIPS) || defined(TARGET_MIPS64)
> -
> -# if defined(TARGET_ABI_MIPSO32)
> -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;
> -};
> -# else /* N32 || N64 */
> -struct target_sigcontext {
> -    uint64_t sc_regs[32];
> -    uint64_t sc_fpregs[32];
> -    uint64_t sc_mdhi;
> -    uint64_t sc_hi1;
> -    uint64_t sc_hi2;
> -    uint64_t sc_hi3;
> -    uint64_t sc_mdlo;
> -    uint64_t sc_lo1;
> -    uint64_t sc_lo2;
> -    uint64_t sc_lo3;
> -    uint64_t sc_pc;
> -    uint32_t sc_fpc_csr;
> -    uint32_t sc_used_math;
> -    uint32_t sc_dsp;
> -    uint32_t sc_reserved;
> -};
> -# endif /* O32 */
> -
> -struct sigframe {
> -    uint32_t sf_ass[4];			/* argument save space for o32 */
> -    uint32_t sf_code[2];			/* signal trampoline */
> -    struct target_sigcontext sf_sc;
> -    target_sigset_t sf_mask;
> -};
> -
> -struct target_ucontext {
> -    target_ulong tuc_flags;
> -    target_ulong tuc_link;
> -    target_stack_t tuc_stack;
> -    target_ulong pad0;
> -    struct target_sigcontext tuc_mcontext;
> -    target_sigset_t tuc_sigmask;
> -};
> -
> -struct target_rt_sigframe {
> -    uint32_t rs_ass[4];               /* argument save space for o32 */
> -    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)
> -{
> -    int err = 0;
> -
> -    /*
> -     * Set up the return code ...
> -     *
> -     *         li      v0, __NR__foo_sigreturn
> -     *         syscall
> -     */
> -
> -    __put_user(0x24020000 + syscall, tramp + 0);
> -    __put_user(0x0000000c          , tramp + 1);
> -    return err;
> -}
> -
> -static inline void setup_sigcontext(CPUMIPSState *regs,
> -                                    struct target_sigcontext *sc)
> -{
> -    int i;
> -
> -    __put_user(exception_resume_pc(regs), &sc->sc_pc);
> -    regs->hflags &= ~MIPS_HFLAG_BMASK;
> -
> -    __put_user(0, &sc->sc_regs[0]);
> -    for (i = 1; i < 32; ++i) {
> -        __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
> -    }
> -
> -    __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
> -    __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
> -
> -    /* Rather than checking for dsp existence, always copy.  The storage
> -       would just be garbage otherwise.  */
> -    __put_user(regs->active_tc.HI[1], &sc->sc_hi1);
> -    __put_user(regs->active_tc.HI[2], &sc->sc_hi2);
> -    __put_user(regs->active_tc.HI[3], &sc->sc_hi3);
> -    __put_user(regs->active_tc.LO[1], &sc->sc_lo1);
> -    __put_user(regs->active_tc.LO[2], &sc->sc_lo2);
> -    __put_user(regs->active_tc.LO[3], &sc->sc_lo3);
> -    {
> -        uint32_t dsp = cpu_rddsp(0x3ff, regs);
> -        __put_user(dsp, &sc->sc_dsp);
> -    }
> -
> -    __put_user(1, &sc->sc_used_math);
> -
> -    for (i = 0; i < 32; ++i) {
> -        __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
> -    }
> -}
> -
> -static inline void
> -restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
> -{
> -    int i;
> -
> -    __get_user(regs->CP0_EPC, &sc->sc_pc);
> -
> -    __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
> -    __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
> -
> -    for (i = 1; i < 32; ++i) {
> -        __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
> -    }
> -
> -    __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
> -    __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
> -    __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
> -    __get_user(regs->active_tc.LO[1], &sc->sc_lo1);
> -    __get_user(regs->active_tc.LO[2], &sc->sc_lo2);
> -    __get_user(regs->active_tc.LO[3], &sc->sc_lo3);
> -    {
> -        uint32_t dsp;
> -        __get_user(dsp, &sc->sc_dsp);
> -        cpu_wrdsp(dsp, 0x3ff, regs);
> -    }
> -
> -    for (i = 0; i < 32; ++i) {
> -        __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
> -    }
> -}
> -
> -/*
> - * Determine which stack to use..
> - */
> -static inline abi_ulong
> -get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
> -{
> -    unsigned long sp;
> -
> -    /* Default to using normal stack */
> -    sp = regs->active_tc.gpr[29];
> -
> -    /*
> -     * FPU emulator may have its 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 mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
> -{
> -    if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
> -        env->hflags &= ~MIPS_HFLAG_M16;
> -        env->hflags |= (env->active_tc.PC & 1) << MIPS_HFLAG_M16_SHIFT;
> -        env->active_tc.PC &= ~(target_ulong) 1;
> -    }
> -}
> -
> -# if defined(TARGET_ABI_MIPSO32)
> -/* compare linux/arch/mips/kernel/signal.c:setup_frame() */
> -static void setup_frame(int sig, struct target_sigaction * ka,
> -                        target_sigset_t *set, CPUMIPSState *regs)
> -{
> -    struct sigframe *frame;
> -    abi_ulong frame_addr;
> -    int i;
> -
> -    frame_addr = get_sigframe(ka, regs, sizeof(*frame));
> -    trace_user_setup_frame(regs, frame_addr);
> -    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
> -        goto give_sigsegv;
> -    }
> -
> -    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);
> -
> -    setup_sigcontext(regs, &frame->sf_sc);
> -
> -    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
> -        __put_user(set->sig[i], &frame->sf_mask.sig[i]);
> -    }
> -
> -    /*
> -    * Arguments to signal handler:
> -    *
> -    *   a0 = signal number
> -    *   a1 = 0 (should be cause)
> -    *   a2 = pointer to struct sigcontext
> -    *
> -    * $25 and PC point to the signal handler, $29 points to the
> -    * struct sigframe.
> -    */
> -    regs->active_tc.gpr[ 4] = sig;
> -    regs->active_tc.gpr[ 5] = 0;
> -    regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);
> -    regs->active_tc.gpr[29] = frame_addr;
> -    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_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 */
> -    regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;
> -    mips_set_hflags_isa_mode_from_pc(regs);
> -    unlock_user_struct(frame, frame_addr, 1);
> -    return;
> -
> -give_sigsegv:
> -    force_sigsegv(sig);
> -}
> -
> -long do_sigreturn(CPUMIPSState *regs)
> -{
> -    struct sigframe *frame;
> -    abi_ulong frame_addr;
> -    sigset_t blocked;
> -    target_sigset_t target_set;
> -    int i;
> -
> -    frame_addr = regs->active_tc.gpr[29];
> -    trace_user_do_sigreturn(regs, frame_addr);
> -    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))
> -        goto badframe;
> -
> -    for(i = 0; i < TARGET_NSIG_WORDS; i++) {
> -        __get_user(target_set.sig[i], &frame->sf_mask.sig[i]);
> -    }
> -
> -    target_to_host_sigset_internal(&blocked, &target_set);
> -    set_sigmask(&blocked);
> -
> -    restore_sigcontext(regs, &frame->sf_sc);
> -
> -#if 0
> -    /*
> -     * Don't let your children do this ...
> -     */
> -    __asm__ __volatile__(
> -   	"move\t$29, %0\n\t"
> -   	"j\tsyscall_exit"
> -   	:/* no outputs */
> -   	:"r" (&regs));
> -    /* Unreached */
> -#endif
> -
> -    regs->active_tc.PC = regs->CP0_EPC;
> -    mips_set_hflags_isa_mode_from_pc(regs);
> -    /* I am not sure this is right, but it seems to work
> -    * maybe a problem with nested signals ? */
> -    regs->CP0_EPC = 0;
> -    return -TARGET_QEMU_ESIGRETURN;
> -
> -badframe:
> -    force_sig(TARGET_SIGSEGV);
> -    return -TARGET_QEMU_ESIGRETURN;
> -}
> -# endif /* O32 */
> -
> -static void setup_rt_frame(int sig, struct target_sigaction *ka,
> -                           target_siginfo_t *info,
> -                           target_sigset_t *set, CPUMIPSState *env)
> -{
> -    struct target_rt_sigframe *frame;
> -    abi_ulong frame_addr;
> -    int i;
> -
> -    frame_addr = get_sigframe(ka, env, sizeof(*frame));
> -    trace_user_setup_rt_frame(env, frame_addr);
> -    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
> -        goto give_sigsegv;
> -    }
> -
> -    install_sigtramp(frame->rs_code, TARGET_NR_rt_sigreturn);
> -
> -    tswap_siginfo(&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 siginfo_t
> -    *   a2 = pointer to ucontext_t
> -    *
> -    * $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;
> -    mips_set_hflags_isa_mode_from_pc(env);
> -    unlock_user_struct(frame, frame_addr, 1);
> -    return;
> -
> -give_sigsegv:
> -    unlock_user_struct(frame, frame_addr, 1);
> -    force_sigsegv(sig);
> -}
> -
> -long do_rt_sigreturn(CPUMIPSState *env)
> -{
> -    struct target_rt_sigframe *frame;
> -    abi_ulong frame_addr;
> -    sigset_t blocked;
> -
> -    frame_addr = env->active_tc.gpr[29];
> -    trace_user_do_rt_sigreturn(env, frame_addr);
> -    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
> -        goto badframe;
> -    }
> -
> -    target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
> -    set_sigmask(&blocked);
> -
> -    restore_sigcontext(env, &frame->rs_uc.tuc_mcontext);
> -
> -    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;
> -    mips_set_hflags_isa_mode_from_pc(env);
> -    /* I am not sure this is right, but it seems to work
> -    * maybe a problem with nested signals ? */
> -    env->CP0_EPC = 0;
> -    return -TARGET_QEMU_ESIGRETURN;
> -
> -badframe:
> -    force_sig(TARGET_SIGSEGV);
> -    return -TARGET_QEMU_ESIGRETURN;
> -}
> -
> -#elif defined(TARGET_PPC)
> +#if defined(TARGET_PPC)
>  
>  /* Size of dummy stack frame allocated when calling signal handler.
>     See arch/powerpc/include/asm/ptrace.h.  */
> 

  reply	other threads:[~2018-03-24  0:57 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-23 22:57 [Qemu-devel] [PATCH for 2.13 v2 00/20] linux-user: move arch specific parts to arch directories Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 01/20] linux-user: create a dummy per arch signal.c Laurent Vivier
2018-03-28 13:55   ` Alex Bennée
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 02/20] linux-user: move aarch64 signal.c parts to aarch64 directory Laurent Vivier
2018-03-28 14:33   ` Alex Bennée
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 03/20] linux-user: move arm signal.c parts to arm directory Laurent Vivier
2018-03-28 14:34   ` Alex Bennée
2018-03-28 14:35   ` Alex Bennée
2018-03-28 14:40     ` Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 04/20] linux-user: move sh4 signal.c parts to sh4 directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 05/20] linux-user: move microblaze signal.c parts to microblaze directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 06/20] linux-user: move cris signal.c parts to cris directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 07/20] linux-user: move nios2 signal.c parts to nios2 directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 08/20] linux-user: move openrisc signal.c parts to openrisc directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 09/20] linux-user: move s390x signal.c parts to s390x directory Laurent Vivier
2018-03-27  8:47   ` Cornelia Huck
2018-03-27  9:13     ` Laurent Vivier
2018-03-27  9:33       ` Cornelia Huck
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 10/20] linux-user: move m68k signal.c parts to m68k directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 11/20] linux-user: move alpha signal.c parts to alpha directory Laurent Vivier
2018-03-24  0:58   ` Philippe Mathieu-Daudé
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 12/20] linux-user: move tilegx signal.c parts to tilegx directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 13/20] linux-user: move riscv signal.c parts to riscv directory Laurent Vivier
2018-03-24  1:04   ` Philippe Mathieu-Daudé
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 14/20] linux-user: move hppa signal.c parts to hppa directory Laurent Vivier
2018-03-24  1:05   ` Philippe Mathieu-Daudé
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 15/20] linux-user: move xtensa signal.c parts to xtensa directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 16/20] linux-user: move i386/x86_64 signal.c parts to i386 directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 17/20] linux-user: move sparc/sparc64 signal.c parts to sparc directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 18/20] linux-user: move mips/mips64 signal.c parts to mips directory Laurent Vivier
2018-03-24  0:57   ` Philippe Mathieu-Daudé [this message]
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 19/20] linux-user: move ppc/ppc64 signal.c parts to ppc directory Laurent Vivier
2018-03-23 22:57 ` [Qemu-devel] [PATCH for 2.13 v2 20/20] linux-user: define TARGET_ARCH_HAS_SETUP_FRAME Laurent Vivier
2018-03-24  0:32 ` [Qemu-devel] [PATCH for 2.13 v2 00/20] linux-user: move arch specific parts to arch directories no-reply
2018-03-28  5:56 ` Richard Henderson
2018-03-28 14:41 ` Alex Bennée
2018-03-28 14:44   ` Daniel P. Berrangé
2018-03-28 14:52   ` Laurent Vivier

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=94189782-743d-12a1-f992-1aa60cb9113c@amsat.org \
    --to=f4bug@amsat.org \
    --cc=cohuck@redhat.com \
    --cc=laurent@vivier.eu \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@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.