On Tue, 2022-08-16 at 15:33 -0500, Richard Henderson wrote: > We're about to start validating PAGE_EXEC, which means that we've > got to the vsyscall page executable. We had been special casing > this entirely within translate. > > Signed-off-by: Richard Henderson <richard.hender...@linaro.org> > --- > linux-user/elfload.c | 22 ++++++++++++++++++++++ > 1 file changed, 22 insertions(+) > > diff --git a/linux-user/elfload.c b/linux-user/elfload.c > index 29d910c4cc..d783240a36 100644 > --- a/linux-user/elfload.c > +++ b/linux-user/elfload.c > @@ -195,6 +195,28 @@ static void > elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en > (*regs)[26] = tswapreg(env->segs[R_GS].selector & 0xffff); > } > > +#if ULONG_MAX >= TARGET_VSYSCALL_PAGE > +#define HI_COMMPAGE TARGET_VSYSCALL_PAGE > + > +static bool init_guest_commpage(void) > +{ > + /* > + * The vsyscall page is at a high negative address aka kernel > space, > + * which means that we cannot actually allocate it with > target_mmap. > + * We still should be able to use page_set_flags, unless the > user > + * has specified -R reserved_va, which would trigger an > assert(). > + */ > + if (reserved_va != 0 && > + TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE >= reserved_va) { > + error_report("Cannot allocate vsyscall page"); > + exit(EXIT_FAILURE); > + } > + page_set_flags(TARGET_VSYSCALL_PAGE, > + TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE, > + PAGE_EXEC | PAGE_VALID); > + return true; > +} > +#endif > #else > > #define ELF_START_MMAP 0x80000000
I found this in context of wasmtime, but apparently the problem is more broad: after this patch any x86_64 PIE binaries no longer run: qemu-x86_64: ../linux-user/elfload.c:2657: pgb_dynamic: Assertion `sizeof(uintptr_t) == 4' failed. Aborted (core dumped) (Maybe we need a test for this, PIE version of "hello world" will do.) I wonder if we need this assert at all? There is a comment that says that 64-bit hosts should have used reserved_va, but what is the reasoning behind this restriction? Without this assert, pgb_find_hole() finds a suitable hole just fine.