[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [qemu-s390x] [PATCH for 2.13 v2 18/20] linux-user: move mips/mips64
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [qemu-s390x] [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 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 |
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 <address@hidden>
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>
> ---
> 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" (®s));
> + /* 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" (®s));
> - /* 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. */
>
- Re: [qemu-s390x] [PATCH for 2.13 v2 13/20] linux-user: move riscv signal.c parts to riscv directory, (continued)
- [qemu-s390x] [PATCH for 2.13 v2 07/20] linux-user: move nios2 signal.c parts to nios2 directory, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 10/20] linux-user: move m68k signal.c parts to m68k directory, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 01/20] linux-user: create a dummy per arch signal.c, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 11/20] linux-user: move alpha signal.c parts to alpha directory, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 15/20] linux-user: move xtensa signal.c parts to xtensa directory, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 12/20] linux-user: move tilegx signal.c parts to tilegx directory, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 18/20] linux-user: move mips/mips64 signal.c parts to mips directory, Laurent Vivier, 2018/03/23
- Re: [qemu-s390x] [PATCH for 2.13 v2 18/20] linux-user: move mips/mips64 signal.c parts to mips directory,
Philippe Mathieu-Daudé <=
- [qemu-s390x] [PATCH for 2.13 v2 03/20] linux-user: move arm signal.c parts to arm directory, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 19/20] linux-user: move ppc/ppc64 signal.c parts to ppc directory, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 17/20] linux-user: move sparc/sparc64 signal.c parts to sparc directory, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 20/20] linux-user: define TARGET_ARCH_HAS_SETUP_FRAME, Laurent Vivier, 2018/03/23
- [qemu-s390x] [PATCH for 2.13 v2 16/20] linux-user: move i386/x86_64 signal.c parts to i386 directory, Laurent Vivier, 2018/03/23
- Re: [qemu-s390x] [Qemu-devel] [PATCH for 2.13 v2 00/20] linux-user: move arch specific parts to arch directories, no-reply, 2018/03/23
- Re: [qemu-s390x] [Qemu-devel] [PATCH for 2.13 v2 00/20] linux-user: move arch specific parts to arch directories, Richard Henderson, 2018/03/28