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