All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Vivier <laurent@vivier.eu>
To: Richard Henderson <richard.henderson@linaro.org>, qemu-devel@nongnu.org
Subject: Re: [PATCH v2 4/7] linux-user/nios2: Map a real kuser page
Date: Wed, 5 Jan 2022 11:24:11 +0100	[thread overview]
Message-ID: <38b13608-ca80-1c5e-bb28-754186d77642@vivier.eu> (raw)
In-Reply-To: <20211221025012.1057923-5-richard.henderson@linaro.org>

Le 21/12/2021 à 03:50, Richard Henderson a écrit :
> The first word of page1 is data, so the whole thing
> can't be implemented with emulation of addresses.
> Use init_guest_commpage for the allocation.
> 
> Hijack trap number 16 to implement cmpxchg.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   linux-user/elfload.c        | 50 ++++++++++++++++++++++++++++++++++++-
>   linux-user/nios2/cpu_loop.c | 50 ++++++++++++++++++++-----------------
>   target/nios2/translate.c    |  9 -------
>   3 files changed, 76 insertions(+), 33 deletions(-)
> 
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index d34cd4fe43..329b2375ef 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -1099,6 +1099,47 @@ static void init_thread(struct target_pt_regs *regs, struct image_info *infop)
>       regs->estatus = 0x3;
>   }
>   
> +#define LO_COMMPAGE  TARGET_PAGE_SIZE
> +
> +static bool init_guest_commpage(void)
> +{
> +    static const uint8_t kuser_page[4 + 2 * 64] = {
> +        /* __kuser_helper_version */
> +        [0x00] = 0x02, 0x00, 0x00, 0x00,
> +
> +        /* __kuser_cmpxchg */
> +        [0x04] = 0x3a, 0x6c, 0x3b, 0x00,  /* trap 16 */
> +                 0x3a, 0x28, 0x00, 0xf8,  /* ret */
> +
> +        /* __kuser_sigtramp */
> +        [0x44] = 0xc4, 0x22, 0x80, 0x00,  /* movi r2, __NR_rt_sigreturn */
> +                 0x3a, 0x68, 0x3b, 0x00,  /* trap 0 */
> +    };
> +
> +    void *want = g2h_untagged(LO_COMMPAGE & -qemu_host_page_size);
> +    void *addr = mmap(want, qemu_host_page_size, PROT_READ | PROT_WRITE,
> +                      MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
> +
> +    if (addr == MAP_FAILED) {
> +        perror("Allocating guest commpage");
> +        exit(EXIT_FAILURE);
> +    }
> +    if (addr != want) {
> +        return false;
> +    }
> +
> +    memcpy(addr, kuser_page, sizeof(kuser_page));
> +
> +    if (mprotect(addr, qemu_host_page_size, PROT_READ)) {
> +        perror("Protecting guest commpage");
> +        exit(EXIT_FAILURE);
> +    }
> +
> +    page_set_flags(LO_COMMPAGE, LO_COMMPAGE + TARGET_PAGE_SIZE,
> +                   PAGE_READ | PAGE_EXEC | PAGE_VALID);
> +    return true;
> +}
> +
>   #define ELF_EXEC_PAGESIZE        4096
>   
>   #define USE_ELF_CORE_DUMP
> @@ -2160,8 +2201,13 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
>       return sp;
>   }
>   
> -#ifndef HI_COMMPAGE
> +#if defined(HI_COMMPAGE)
> +#define LO_COMMPAGE 0
> +#elif defined(LO_COMMPAGE)
>   #define HI_COMMPAGE 0
> +#else
> +#define HI_COMMPAGE 0
> +#define LO_COMMPAGE 0
>   #define init_guest_commpage() true
>   #endif
>   
> @@ -2374,6 +2420,8 @@ static void pgb_static(const char *image_name, abi_ulong orig_loaddr,
>           } else {
>               offset = -(HI_COMMPAGE & -align);
>           }
> +    } else if (LO_COMMPAGE) {
> +        loaddr = MIN(loaddr, LO_COMMPAGE & -align);
>       }
>   
>       addr = pgb_find_hole(loaddr, hiaddr - loaddr, align, offset);
> diff --git a/linux-user/nios2/cpu_loop.c b/linux-user/nios2/cpu_loop.c
> index 5c3d01d22d..de0fc63e21 100644
> --- a/linux-user/nios2/cpu_loop.c
> +++ b/linux-user/nios2/cpu_loop.c
> @@ -76,6 +76,32 @@ void cpu_loop(CPUNios2State *env)
>                   force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLTRP,
>                                   env->regs[R_PC]);
>                   break;
> +
> +            case 16: /* QEMU specific, for __kuser_cmpxchg */
> +                {
> +                    abi_ptr g = env->regs[4];
> +                    uint32_t *h, n, o;
> +
> +                    if (g & 0x3) {
> +                        force_sig_fault(TARGET_SIGBUS, TARGET_BUS_ADRALN, g);
> +                        break;
> +                    }
> +                    ret = page_get_flags(g);
> +                    if (!(ret & PAGE_VALID)) {
> +                        force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, g);
> +                        break;
> +                    }
> +                    if (!(ret & PAGE_READ) || !(ret & PAGE_WRITE)) {
> +                        force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_ACCERR, g);
> +                        break;
> +                    }
> +                    h = g2h(cs, g);
> +                    o = env->regs[5];
> +                    n = env->regs[6];
> +                    env->regs[2] = qatomic_cmpxchg(h, o, n) - o;
> +                    env->regs[R_PC] += 4;
> +                }
> +                break;
>               }
>               break;
>   
> @@ -86,29 +112,7 @@ void cpu_loop(CPUNios2State *env)
>               queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
>               break;
>           case 0xaa:
> -            switch (env->regs[R_PC]) {
> -            /*case 0x1000:*/  /* TODO:__kuser_helper_version */
> -            case 0x1004:      /* __kuser_cmpxchg */
> -                start_exclusive();
> -                if (env->regs[4] & 0x3) {
> -                    goto kuser_fail;
> -                }
> -                ret = get_user_u32(env->regs[2], env->regs[4]);
> -                if (ret) {
> -                    end_exclusive();
> -                    goto kuser_fail;
> -                }
> -                env->regs[2] -= env->regs[5];
> -                if (env->regs[2] == 0) {
> -                    put_user_u32(env->regs[6], env->regs[4]);
> -                }
> -                end_exclusive();
> -                env->regs[R_PC] = env->regs[R_RA];
> -                break;
> -            /*case 0x1040:*/  /* TODO:__kuser_sigtramp */
> -            default:
> -                ;
> -kuser_fail:
> +            {
>                   info.si_signo = TARGET_SIGSEGV;
>                   info.si_errno = 0;
>                   /* TODO: check env->error_code */
> diff --git a/target/nios2/translate.c b/target/nios2/translate.c
> index a759877519..f9abc2fdd2 100644
> --- a/target/nios2/translate.c
> +++ b/target/nios2/translate.c
> @@ -795,15 +795,6 @@ static void nios2_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
>       dc->base.pc_next = pc + 4;
>   
>       /* Decode an instruction */
> -
> -#if defined(CONFIG_USER_ONLY)
> -    /* FIXME: Is this needed ? */
> -    if (pc >= 0x1000 && pc < 0x2000) {
> -        t_gen_helper_raise_exception(dc, 0xaa);
> -        return;
> -    }
> -#endif
> -
>       code = cpu_ldl_code(env, pc);
>       op = get_opcode(code);
>   

Applied to my linux-user-for-7.0 branch.

Thanks,
Laurent



  parent reply	other threads:[~2022-01-05 10:41 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-21  2:50 [PATCH v2 0/7] linux-user: nios2 fixes Richard Henderson
2021-12-21  2:50 ` [PATCH v2 1/7] linux-user/nios2: Properly emulate EXCP_TRAP Richard Henderson
2021-12-22 18:52   ` Laurent Vivier
2022-01-05 10:23   ` Laurent Vivier
2021-12-21  2:50 ` [PATCH v2 2/7] linux-user/nios2: Fixes for signal frame setup Richard Henderson
2022-01-05 10:23   ` Laurent Vivier
2021-12-21  2:50 ` [PATCH v2 3/7] linux-user/elfload: Rename ARM_COMMPAGE to HI_COMMPAGE Richard Henderson
2022-01-05 10:24   ` Laurent Vivier
2021-12-21  2:50 ` [PATCH v2 4/7] linux-user/nios2: Map a real kuser page Richard Henderson
2021-12-22 20:18   ` Laurent Vivier
2022-01-05 10:24   ` Laurent Vivier [this message]
2021-12-21  2:50 ` [PATCH v2 5/7] linux-user/nios2: Fix EA vs PC confusion Richard Henderson
2021-12-22 20:20   ` Laurent Vivier
2022-01-05 10:24   ` Laurent Vivier
2021-12-21  2:50 ` [PATCH v2 6/7] linux-user/nios2: Fix sigmask in setup_rt_frame Richard Henderson
2022-01-05 10:24   ` Laurent Vivier
2021-12-21  2:50 ` [PATCH v2 7/7] linux-user/nios2: Use set_sigmask in do_rt_sigreturn Richard Henderson
2022-01-05 10:24   ` 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=38b13608-ca80-1c5e-bb28-754186d77642@vivier.eu \
    --to=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /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.