Richard Henderson <richard.hender...@linaro.org> writes:
> Notice the magic page during translate, much like we already > do for the arm32 commpage. At runtime, raise an exception to > return cpu_loop for emulation. > > Reviewed-by: Paolo Bonzini <pbonz...@redhat.com> > Signed-off-by: Richard Henderson <richard.hender...@linaro.org> > --- > target/i386/cpu.h | 1 + > linux-user/i386/cpu_loop.c | 105 +++++++++++++++++++++++++++++++++++++ > target/i386/translate.c | 16 +++++- > 3 files changed, 121 insertions(+), 1 deletion(-) > > diff --git a/target/i386/cpu.h b/target/i386/cpu.h > index 164d038d1f..3fb2d2a986 100644 > --- a/target/i386/cpu.h > +++ b/target/i386/cpu.h > @@ -1000,6 +1000,7 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS]; > > #define EXCP_VMEXIT 0x100 /* only for system emulation */ > #define EXCP_SYSCALL 0x101 /* only for user emulation */ > +#define EXCP_VSYSCALL 0x102 /* only for user emulation */ > > /* i386-specific interrupt pending bits. */ > #define CPU_INTERRUPT_POLL CPU_INTERRUPT_TGT_EXT_1 > diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c > index e217cca5ee..f9bf6cec27 100644 > --- a/linux-user/i386/cpu_loop.c > +++ b/linux-user/i386/cpu_loop.c > @@ -92,6 +92,106 @@ static void gen_signal(CPUX86State *env, int sig, int > code, abi_ptr addr) > queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); > } > > +#ifdef TARGET_X86_64 > +static bool write_ok_or_segv(CPUX86State *env, abi_ptr addr, size_t len) > +{ > + /* > + * For all the vsyscalls, NULL means "don't write anything" not > + * "write it at address 0". > + */ > + if (addr == 0 || access_ok(VERIFY_WRITE, addr, len)) { > + return true; > + } > + > + env->error_code = PG_ERROR_W_MASK | PG_ERROR_U_MASK; > + gen_signal(env, TARGET_SIGSEGV, TARGET_SEGV_MAPERR, addr); > + return false; > +} > + > +/* > + * Since v3.1, the kernel traps and emulates the vsyscall page. > + * Entry points other than the official generate SIGSEGV. > + */ > +static void emulate_vsyscall(CPUX86State *env) > +{ > + int syscall; > + abi_ulong ret; > + uint64_t caller; > + > + /* > + * Validate the entry point. We have already validated the page > + * during translation, now verify the offset. > + */ > + switch (env->eip & ~TARGET_PAGE_MASK) { > + case 0x000: > + syscall = TARGET_NR_gettimeofday; > + break; > + case 0x400: > + syscall = TARGET_NR_time; > + break; > + case 0x800: > + syscall = TARGET_NR_getcpu; > + break; > + default: > + sigsegv: this label looks a little extraneous. Otherwise: Reviewed-by: Alex Bennée <alex.ben...@linaro.org> -- Alex Bennée