Le 02/03/2018 à 14:51, Michael Clark a écrit :
> Implementation of linux user emulation for RISC-V.
> 
> Reviewed-by: Richard Henderson <richard.hender...@linaro.org>
> Signed-off-by: Sagar Karandikar <sag...@eecs.berkeley.edu>
> Signed-off-by: Michael Clark <m...@sifive.com>
> ---
>  linux-user/elfload.c              |  22 +++
>  linux-user/main.c                 |  99 +++++++++++++
>  linux-user/riscv/syscall_nr.h     | 287 
> ++++++++++++++++++++++++++++++++++++++
>  linux-user/riscv/target_cpu.h     |  18 +++
>  linux-user/riscv/target_elf.h     |  14 ++
>  linux-user/riscv/target_signal.h  |  23 +++
>  linux-user/riscv/target_structs.h |  46 ++++++
>  linux-user/riscv/target_syscall.h |  56 ++++++++
>  linux-user/riscv/termbits.h       | 222 +++++++++++++++++++++++++++++
>  linux-user/signal.c               | 203 ++++++++++++++++++++++++++-
>  linux-user/syscall.c              |   2 +
>  linux-user/syscall_defs.h         |  13 +-
>  target/riscv/cpu_user.h           |  13 ++
>  13 files changed, 1012 insertions(+), 6 deletions(-)
>  create mode 100644 linux-user/riscv/syscall_nr.h
>  create mode 100644 linux-user/riscv/target_cpu.h
>  create mode 100644 linux-user/riscv/target_elf.h
>  create mode 100644 linux-user/riscv/target_signal.h
>  create mode 100644 linux-user/riscv/target_structs.h
>  create mode 100644 linux-user/riscv/target_syscall.h
>  create mode 100644 linux-user/riscv/termbits.h
>  create mode 100644 target/riscv/cpu_user.h
> 
...
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index 9a380b9..4d3f244 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
...
> +static abi_ulong get_sigframe(struct target_sigaction *ka,
> +                              CPURISCVState *regs, size_t framesize)
> +{
> +    abi_ulong sp = regs->gpr[xSP];
> +    int onsigstack = on_sig_stack(sp);
> +
> +    /* redzone */
> +    /* This is the X/Open sanctioned signal stack switching.  */
> +    if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !onsigstack) {
> +        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
> +    }
> +
> +    sp -= framesize;
> +    sp &= ~3UL; /* align sp on 4-byte boundary */

kernel aligns using 0xf. Why do you use a different alignment?

> +
> +    /* If we are on the alternate signal stack and would overflow it, don't.
> +       Return an always-bogus address instead so we will die with SIGSEGV. */
> +    if (onsigstack && !likely(on_sig_stack(sp))) {
> +        return -1L;
> +    }
> +
> +    return sp;
> +}
Other question why don't you use the same logic as in kernel?

1- check for signal stack overflow
2- check for X/Open sanctioned signal stack switching

static inline void __user *get_sigframe(struct ksignal *ksig,
        struct pt_regs *regs, size_t framesize)
{
        unsigned long sp;
        /* Default to using normal stack */
        sp = regs->sp;

        /*
         * If we are on the alternate signal stack and would overflow
it, don't.
         * Return an always-bogus address instead so we will die with
SIGSEGV.
         */
        if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
                return (void __user __force *)(-1UL);

        /* This is the X/Open sanctioned signal stack switching. */
        sp = sigsp(sp, ksig) - framesize;

        /* Align the stack frame. */
        sp &= ~0xfUL;

        return (void __user *)sp;
}

Thanks,
Laurent

Reply via email to