On Fri, 24 Sept 2021 at 17:59, Richard Henderson
<richard.hender...@linaro.org> wrote:
>
> The first word of page1 is data, so the whole thing
> can't be implemented with emulation of addresses.
>
> Hijack trap number 31 to implement cmpxchg.

31 is used -- it's "breakpoint". We need to pick something else...

>
> Set default_rt_sigreturn based on the kuser page.
>
> Signed-off-by: Richard Henderson <richard.hender...@linaro.org>
> ---
>  linux-user/nios2/target_signal.h |  3 ++
>  linux-user/elfload.c             | 35 ++++++++++++++++++++++
>  linux-user/nios2/cpu_loop.c      | 51 +++++++++++++++++---------------
>  linux-user/nios2/signal.c        |  2 +-
>  target/nios2/translate.c         |  9 ------
>  5 files changed, 66 insertions(+), 34 deletions(-)
>
> diff --git a/linux-user/nios2/target_signal.h 
> b/linux-user/nios2/target_signal.h
> index aebf749f12..fe266c4c51 100644
> --- a/linux-user/nios2/target_signal.h
> +++ b/linux-user/nios2/target_signal.h
> @@ -19,4 +19,7 @@ typedef struct target_sigaltstack {
>
>  #include "../generic/signal.h"
>
> +/* Nios2 uses a fixed address on the kuser page for sigreturn. */
> +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
> +
>  #endif /* NIOS2_TARGET_SIGNAL_H */
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 459a26ef1d..7b3a91b3ed 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -1100,6 +1100,41 @@ static void elf_core_copy_regs(target_elf_gregset_t 
> *regs, const CPUMBState *env
>
>  static void init_thread(struct target_pt_regs *regs, struct image_info 
> *infop)
>  {
> +    static const uint8_t kuser_page[4 + 2 * 64] = {
> +        /* __kuser_helper_version */
> +        [0x00] = 0x02, 0x00, 0x00, 0x00,
> +
> +        /* __kuser_cmpxchg */
> +        [0x04] = 0xfa, 0x6f, 0x3b, 0x00,  /* trap 31 */
> +                 0x3a, 0x28, 0x00, 0xf8,  /* ret */
> +
> +        /* __kuser_sigtramp */
> +        [0x44] = 0xc4, 0x22, 0x80, 0x00,  /* movi r2, __NR_rt_sigreturn */
> +                 0x3a, 0x68, 0x3b, 0x00,  /* trap 0 */
> +    };
> +
> +    abi_ulong pg;
> +    uint8_t *ph;
> +
> +    pg = target_mmap(TARGET_PAGE_SIZE, TARGET_PAGE_SIZE,
> +                     PROT_READ | PROT_WRITE,
> +                     MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0);
> +
> +    /*
> +     * If the mmap doesn't give us exactly page 1, there's nothing
> +     * we can do, and it's unlikely that the program will be able
> +     * to continue.  FIXME: Error out now?
> +     */
> +    assert(pg == TARGET_PAGE_SIZE);

Shouldn't we be doing this via the probe_guest_base machinery
the way we do for the Arm commpage ?

> +
> +    ph = lock_user(VERIFY_WRITE, pg, sizeof(kuser_page), 0);
> +    memcpy(ph, kuser_page, sizeof(kuser_page));
> +    unlock_user(ph, pg, sizeof(kuser_page));
> +    target_mprotect(TARGET_PAGE_SIZE, TARGET_PAGE_SIZE, PROT_READ | 
> PROT_EXEC);
> +
> +    /* Install __kuser_sigtramp */
> +    default_rt_sigreturn = TARGET_PAGE_SIZE + 0x44;
> +
>      regs->ea = infop->entry;
>      regs->sp = infop->start_stack;
>      regs->estatus = 0x3;

-- PMM

Reply via email to