* [PATCH 1/3] target/i386: Renumber EXCP_SYSCALL
2020-01-14 21:09 [PATCH 0/3] linux-user: Implement x86_64 vsyscalls Richard Henderson
@ 2020-01-14 21:09 ` Richard Henderson
2020-01-15 7:22 ` Philippe Mathieu-Daudé
2020-01-15 9:55 ` Alex Bennée
2020-01-14 21:09 ` [PATCH 2/3] linux-user/i386: Split out gen_signal Richard Henderson
` (6 subsequent siblings)
7 siblings, 2 replies; 21+ messages in thread
From: Richard Henderson @ 2020-01-14 21:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, riku.voipio, laurent, peter.maydell
We are not short of numbers for EXCP_*. There is no need to confuse things
by having EXCP_VMEXIT and EXCP_SYSCALL overlap, even though the former is
only used for system mode and the latter is only used for user mode.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/cpu.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 594326a794..164d038d1f 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -998,9 +998,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
#define EXCP11_ALGN 17
#define EXCP12_MCHK 18
-#define EXCP_SYSCALL 0x100 /* only happens in user only emulation
- for syscall instruction */
-#define EXCP_VMEXIT 0x100
+#define EXCP_VMEXIT 0x100 /* only for system emulation */
+#define EXCP_SYSCALL 0x101 /* only for user emulation */
/* i386-specific interrupt pending bits. */
#define CPU_INTERRUPT_POLL CPU_INTERRUPT_TGT_EXT_1
--
2.20.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 1/3] target/i386: Renumber EXCP_SYSCALL
2020-01-14 21:09 ` [PATCH 1/3] target/i386: Renumber EXCP_SYSCALL Richard Henderson
@ 2020-01-15 7:22 ` Philippe Mathieu-Daudé
2020-01-15 9:55 ` Alex Bennée
1 sibling, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-01-15 7:22 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: pbonzini, riku.voipio, laurent, peter.maydell
On 1/14/20 10:09 PM, Richard Henderson wrote:
> We are not short of numbers for EXCP_*. There is no need to confuse things
> by having EXCP_VMEXIT and EXCP_SYSCALL overlap, even though the former is
> only used for system mode and the latter is only used for user mode.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/cpu.h | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index 594326a794..164d038d1f 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -998,9 +998,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
> #define EXCP11_ALGN 17
> #define EXCP12_MCHK 18
>
> -#define EXCP_SYSCALL 0x100 /* only happens in user only emulation
> - for syscall instruction */
> -#define EXCP_VMEXIT 0x100
> +#define EXCP_VMEXIT 0x100 /* only for system emulation */
> +#define EXCP_SYSCALL 0x101 /* only for user emulation */
>
> /* i386-specific interrupt pending bits. */
> #define CPU_INTERRUPT_POLL CPU_INTERRUPT_TGT_EXT_1
>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/3] target/i386: Renumber EXCP_SYSCALL
2020-01-14 21:09 ` [PATCH 1/3] target/i386: Renumber EXCP_SYSCALL Richard Henderson
2020-01-15 7:22 ` Philippe Mathieu-Daudé
@ 2020-01-15 9:55 ` Alex Bennée
1 sibling, 0 replies; 21+ messages in thread
From: Alex Bennée @ 2020-01-15 9:55 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
Richard Henderson <richard.henderson@linaro.org> writes:
> We are not short of numbers for EXCP_*. There is no need to confuse things
> by having EXCP_VMEXIT and EXCP_SYSCALL overlap, even though the former is
> only used for system mode and the latter is only used for user mode.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> ---
> target/i386/cpu.h | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index 594326a794..164d038d1f 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -998,9 +998,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
> #define EXCP11_ALGN 17
> #define EXCP12_MCHK 18
>
> -#define EXCP_SYSCALL 0x100 /* only happens in user only emulation
> - for syscall instruction */
> -#define EXCP_VMEXIT 0x100
> +#define EXCP_VMEXIT 0x100 /* only for system emulation */
> +#define EXCP_SYSCALL 0x101 /* only for user emulation */
>
> /* i386-specific interrupt pending bits. */
> #define CPU_INTERRUPT_POLL CPU_INTERRUPT_TGT_EXT_1
--
Alex Bennée
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 2/3] linux-user/i386: Split out gen_signal
2020-01-14 21:09 [PATCH 0/3] linux-user: Implement x86_64 vsyscalls Richard Henderson
2020-01-14 21:09 ` [PATCH 1/3] target/i386: Renumber EXCP_SYSCALL Richard Henderson
@ 2020-01-14 21:09 ` Richard Henderson
2020-01-15 7:22 ` Philippe Mathieu-Daudé
2020-01-15 9:58 ` Alex Bennée
2020-01-14 21:09 ` [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls Richard Henderson
` (5 subsequent siblings)
7 siblings, 2 replies; 21+ messages in thread
From: Richard Henderson @ 2020-01-14 21:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, riku.voipio, laurent, peter.maydell
This is a bit tidier than open-coding the 5 lines necessary
to initialize the target_siginfo_t. In addition, this zeros
the remaining bytes of the target_siginfo_t, rather than
passing in garbage.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/i386/cpu_loop.c | 93 ++++++++++++++------------------------
1 file changed, 33 insertions(+), 60 deletions(-)
diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index 024b6f4d58..e217cca5ee 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -81,13 +81,23 @@ static void set_idt(int n, unsigned int dpl)
}
#endif
+static void gen_signal(CPUX86State *env, int sig, int code, abi_ptr addr)
+{
+ target_siginfo_t info = {
+ .si_signo = sig,
+ .si_code = code,
+ ._sifields._sigfault._addr = addr
+ };
+
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+}
+
void cpu_loop(CPUX86State *env)
{
CPUState *cs = env_cpu(env);
int trapnr;
abi_ulong pc;
abi_ulong ret;
- target_siginfo_t info;
for(;;) {
cpu_exec_start(cs);
@@ -134,70 +144,45 @@ void cpu_loop(CPUX86State *env)
#endif
case EXCP0B_NOSEG:
case EXCP0C_STACK:
- info.si_signo = TARGET_SIGBUS;
- info.si_errno = 0;
- info.si_code = TARGET_SI_KERNEL;
- info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ gen_signal(env, TARGET_SIGBUS, TARGET_SI_KERNEL, 0);
break;
case EXCP0D_GPF:
/* XXX: potential problem if ABI32 */
#ifndef TARGET_X86_64
if (env->eflags & VM_MASK) {
handle_vm86_fault(env);
- } else
-#endif
- {
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SI_KERNEL;
- info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ break;
}
+#endif
+ gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
break;
case EXCP0E_PAGE:
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- if (!(env->error_code & 1))
- info.si_code = TARGET_SEGV_MAPERR;
- else
- info.si_code = TARGET_SEGV_ACCERR;
- info._sifields._sigfault._addr = env->cr[2];
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ gen_signal(env, TARGET_SIGSEGV,
+ (env->error_code & 1 ?
+ TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR),
+ env->cr[2]);
break;
case EXCP00_DIVZ:
#ifndef TARGET_X86_64
if (env->eflags & VM_MASK) {
handle_vm86_trap(env, trapnr);
- } else
-#endif
- {
- /* division by zero */
- info.si_signo = TARGET_SIGFPE;
- info.si_errno = 0;
- info.si_code = TARGET_FPE_INTDIV;
- info._sifields._sigfault._addr = env->eip;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ break;
}
+#endif
+ gen_signal(env, TARGET_SIGFPE, TARGET_FPE_INTDIV, env->eip);
break;
case EXCP01_DB:
case EXCP03_INT3:
#ifndef TARGET_X86_64
if (env->eflags & VM_MASK) {
handle_vm86_trap(env, trapnr);
- } else
+ break;
+ }
#endif
- {
- info.si_signo = TARGET_SIGTRAP;
- info.si_errno = 0;
- if (trapnr == EXCP01_DB) {
- info.si_code = TARGET_TRAP_BRKPT;
- info._sifields._sigfault._addr = env->eip;
- } else {
- info.si_code = TARGET_SI_KERNEL;
- info._sifields._sigfault._addr = 0;
- }
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ if (trapnr == EXCP01_DB) {
+ gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
+ } else {
+ gen_signal(env, TARGET_SIGTRAP, TARGET_SI_KERNEL, 0);
}
break;
case EXCP04_INTO:
@@ -205,31 +190,19 @@ void cpu_loop(CPUX86State *env)
#ifndef TARGET_X86_64
if (env->eflags & VM_MASK) {
handle_vm86_trap(env, trapnr);
- } else
-#endif
- {
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SI_KERNEL;
- info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ break;
}
+#endif
+ gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
break;
case EXCP06_ILLOP:
- info.si_signo = TARGET_SIGILL;
- info.si_errno = 0;
- info.si_code = TARGET_ILL_ILLOPN;
- info._sifields._sigfault._addr = env->eip;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPN, env->eip);
break;
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
break;
case EXCP_DEBUG:
- info.si_signo = TARGET_SIGTRAP;
- info.si_errno = 0;
- info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, 0);
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
--
2.20.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/3] linux-user/i386: Split out gen_signal
2020-01-14 21:09 ` [PATCH 2/3] linux-user/i386: Split out gen_signal Richard Henderson
@ 2020-01-15 7:22 ` Philippe Mathieu-Daudé
2020-01-15 9:58 ` Alex Bennée
1 sibling, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-01-15 7:22 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Cc: pbonzini, riku.voipio, laurent, peter.maydell
On 1/14/20 10:09 PM, Richard Henderson wrote:
> This is a bit tidier than open-coding the 5 lines necessary
> to initialize the target_siginfo_t. In addition, this zeros
> the remaining bytes of the target_siginfo_t, rather than
> passing in garbage.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> linux-user/i386/cpu_loop.c | 93 ++++++++++++++------------------------
> 1 file changed, 33 insertions(+), 60 deletions(-)
>
> diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
> index 024b6f4d58..e217cca5ee 100644
> --- a/linux-user/i386/cpu_loop.c
> +++ b/linux-user/i386/cpu_loop.c
> @@ -81,13 +81,23 @@ static void set_idt(int n, unsigned int dpl)
> }
> #endif
>
> +static void gen_signal(CPUX86State *env, int sig, int code, abi_ptr addr)
> +{
> + target_siginfo_t info = {
> + .si_signo = sig,
> + .si_code = code,
> + ._sifields._sigfault._addr = addr
> + };
> +
> + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> +}
> +
> void cpu_loop(CPUX86State *env)
> {
> CPUState *cs = env_cpu(env);
> int trapnr;
> abi_ulong pc;
> abi_ulong ret;
> - target_siginfo_t info;
>
> for(;;) {
> cpu_exec_start(cs);
> @@ -134,70 +144,45 @@ void cpu_loop(CPUX86State *env)
> #endif
> case EXCP0B_NOSEG:
> case EXCP0C_STACK:
> - info.si_signo = TARGET_SIGBUS;
> - info.si_errno = 0;
> - info.si_code = TARGET_SI_KERNEL;
> - info._sifields._sigfault._addr = 0;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + gen_signal(env, TARGET_SIGBUS, TARGET_SI_KERNEL, 0);
> break;
> case EXCP0D_GPF:
> /* XXX: potential problem if ABI32 */
> #ifndef TARGET_X86_64
> if (env->eflags & VM_MASK) {
> handle_vm86_fault(env);
> - } else
> -#endif
> - {
> - info.si_signo = TARGET_SIGSEGV;
> - info.si_errno = 0;
> - info.si_code = TARGET_SI_KERNEL;
> - info._sifields._sigfault._addr = 0;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + break;
> }
> +#endif
> + gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
> break;
> case EXCP0E_PAGE:
> - info.si_signo = TARGET_SIGSEGV;
> - info.si_errno = 0;
> - if (!(env->error_code & 1))
> - info.si_code = TARGET_SEGV_MAPERR;
> - else
> - info.si_code = TARGET_SEGV_ACCERR;
> - info._sifields._sigfault._addr = env->cr[2];
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + gen_signal(env, TARGET_SIGSEGV,
> + (env->error_code & 1 ?
> + TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR),
> + env->cr[2]);
> break;
> case EXCP00_DIVZ:
> #ifndef TARGET_X86_64
> if (env->eflags & VM_MASK) {
> handle_vm86_trap(env, trapnr);
> - } else
> -#endif
> - {
> - /* division by zero */
> - info.si_signo = TARGET_SIGFPE;
> - info.si_errno = 0;
> - info.si_code = TARGET_FPE_INTDIV;
> - info._sifields._sigfault._addr = env->eip;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + break;
> }
> +#endif
> + gen_signal(env, TARGET_SIGFPE, TARGET_FPE_INTDIV, env->eip);
> break;
> case EXCP01_DB:
> case EXCP03_INT3:
> #ifndef TARGET_X86_64
> if (env->eflags & VM_MASK) {
> handle_vm86_trap(env, trapnr);
> - } else
> + break;
> + }
> #endif
> - {
> - info.si_signo = TARGET_SIGTRAP;
> - info.si_errno = 0;
> - if (trapnr == EXCP01_DB) {
> - info.si_code = TARGET_TRAP_BRKPT;
> - info._sifields._sigfault._addr = env->eip;
> - } else {
> - info.si_code = TARGET_SI_KERNEL;
> - info._sifields._sigfault._addr = 0;
> - }
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + if (trapnr == EXCP01_DB) {
> + gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
> + } else {
> + gen_signal(env, TARGET_SIGTRAP, TARGET_SI_KERNEL, 0);
> }
> break;
> case EXCP04_INTO:
> @@ -205,31 +190,19 @@ void cpu_loop(CPUX86State *env)
> #ifndef TARGET_X86_64
> if (env->eflags & VM_MASK) {
> handle_vm86_trap(env, trapnr);
> - } else
> -#endif
> - {
> - info.si_signo = TARGET_SIGSEGV;
> - info.si_errno = 0;
> - info.si_code = TARGET_SI_KERNEL;
> - info._sifields._sigfault._addr = 0;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + break;
> }
> +#endif
> + gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
> break;
> case EXCP06_ILLOP:
> - info.si_signo = TARGET_SIGILL;
> - info.si_errno = 0;
> - info.si_code = TARGET_ILL_ILLOPN;
> - info._sifields._sigfault._addr = env->eip;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPN, env->eip);
> break;
> case EXCP_INTERRUPT:
> /* just indicate that signals should be handled asap */
> break;
> case EXCP_DEBUG:
> - info.si_signo = TARGET_SIGTRAP;
> - info.si_errno = 0;
> - info.si_code = TARGET_TRAP_BRKPT;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, 0);
> break;
> case EXCP_ATOMIC:
> cpu_exec_step_atomic(cs);
>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/3] linux-user/i386: Split out gen_signal
2020-01-14 21:09 ` [PATCH 2/3] linux-user/i386: Split out gen_signal Richard Henderson
2020-01-15 7:22 ` Philippe Mathieu-Daudé
@ 2020-01-15 9:58 ` Alex Bennée
1 sibling, 0 replies; 21+ messages in thread
From: Alex Bennée @ 2020-01-15 9:58 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
Richard Henderson <richard.henderson@linaro.org> writes:
> This is a bit tidier than open-coding the 5 lines necessary
> to initialize the target_siginfo_t. In addition, this zeros
> the remaining bytes of the target_siginfo_t, rather than
> passing in garbage.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> ---
> linux-user/i386/cpu_loop.c | 93 ++++++++++++++------------------------
> 1 file changed, 33 insertions(+), 60 deletions(-)
>
> diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
> index 024b6f4d58..e217cca5ee 100644
> --- a/linux-user/i386/cpu_loop.c
> +++ b/linux-user/i386/cpu_loop.c
> @@ -81,13 +81,23 @@ static void set_idt(int n, unsigned int dpl)
> }
> #endif
>
> +static void gen_signal(CPUX86State *env, int sig, int code, abi_ptr addr)
> +{
> + target_siginfo_t info = {
> + .si_signo = sig,
> + .si_code = code,
> + ._sifields._sigfault._addr = addr
> + };
> +
> + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> +}
> +
> void cpu_loop(CPUX86State *env)
> {
> CPUState *cs = env_cpu(env);
> int trapnr;
> abi_ulong pc;
> abi_ulong ret;
> - target_siginfo_t info;
>
> for(;;) {
> cpu_exec_start(cs);
> @@ -134,70 +144,45 @@ void cpu_loop(CPUX86State *env)
> #endif
> case EXCP0B_NOSEG:
> case EXCP0C_STACK:
> - info.si_signo = TARGET_SIGBUS;
> - info.si_errno = 0;
> - info.si_code = TARGET_SI_KERNEL;
> - info._sifields._sigfault._addr = 0;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + gen_signal(env, TARGET_SIGBUS, TARGET_SI_KERNEL, 0);
> break;
> case EXCP0D_GPF:
> /* XXX: potential problem if ABI32 */
> #ifndef TARGET_X86_64
> if (env->eflags & VM_MASK) {
> handle_vm86_fault(env);
> - } else
> -#endif
> - {
> - info.si_signo = TARGET_SIGSEGV;
> - info.si_errno = 0;
> - info.si_code = TARGET_SI_KERNEL;
> - info._sifields._sigfault._addr = 0;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + break;
> }
> +#endif
> + gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
> break;
> case EXCP0E_PAGE:
> - info.si_signo = TARGET_SIGSEGV;
> - info.si_errno = 0;
> - if (!(env->error_code & 1))
> - info.si_code = TARGET_SEGV_MAPERR;
> - else
> - info.si_code = TARGET_SEGV_ACCERR;
> - info._sifields._sigfault._addr = env->cr[2];
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + gen_signal(env, TARGET_SIGSEGV,
> + (env->error_code & 1 ?
> + TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR),
> + env->cr[2]);
> break;
> case EXCP00_DIVZ:
> #ifndef TARGET_X86_64
> if (env->eflags & VM_MASK) {
> handle_vm86_trap(env, trapnr);
> - } else
> -#endif
> - {
> - /* division by zero */
> - info.si_signo = TARGET_SIGFPE;
> - info.si_errno = 0;
> - info.si_code = TARGET_FPE_INTDIV;
> - info._sifields._sigfault._addr = env->eip;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + break;
> }
> +#endif
> + gen_signal(env, TARGET_SIGFPE, TARGET_FPE_INTDIV, env->eip);
> break;
> case EXCP01_DB:
> case EXCP03_INT3:
> #ifndef TARGET_X86_64
> if (env->eflags & VM_MASK) {
> handle_vm86_trap(env, trapnr);
> - } else
> + break;
> + }
> #endif
> - {
> - info.si_signo = TARGET_SIGTRAP;
> - info.si_errno = 0;
> - if (trapnr == EXCP01_DB) {
> - info.si_code = TARGET_TRAP_BRKPT;
> - info._sifields._sigfault._addr = env->eip;
> - } else {
> - info.si_code = TARGET_SI_KERNEL;
> - info._sifields._sigfault._addr = 0;
> - }
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + if (trapnr == EXCP01_DB) {
> + gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->eip);
> + } else {
> + gen_signal(env, TARGET_SIGTRAP, TARGET_SI_KERNEL, 0);
> }
> break;
> case EXCP04_INTO:
> @@ -205,31 +190,19 @@ void cpu_loop(CPUX86State *env)
> #ifndef TARGET_X86_64
> if (env->eflags & VM_MASK) {
> handle_vm86_trap(env, trapnr);
> - } else
> -#endif
> - {
> - info.si_signo = TARGET_SIGSEGV;
> - info.si_errno = 0;
> - info.si_code = TARGET_SI_KERNEL;
> - info._sifields._sigfault._addr = 0;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + break;
> }
> +#endif
> + gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
> break;
> case EXCP06_ILLOP:
> - info.si_signo = TARGET_SIGILL;
> - info.si_errno = 0;
> - info.si_code = TARGET_ILL_ILLOPN;
> - info._sifields._sigfault._addr = env->eip;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + gen_signal(env, TARGET_SIGILL, TARGET_ILL_ILLOPN, env->eip);
> break;
> case EXCP_INTERRUPT:
> /* just indicate that signals should be handled asap */
> break;
> case EXCP_DEBUG:
> - info.si_signo = TARGET_SIGTRAP;
> - info.si_errno = 0;
> - info.si_code = TARGET_TRAP_BRKPT;
> - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
> + gen_signal(env, TARGET_SIGTRAP, TARGET_TRAP_BRKPT, 0);
> break;
> case EXCP_ATOMIC:
> cpu_exec_step_atomic(cs);
--
Alex Bennée
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls
2020-01-14 21:09 [PATCH 0/3] linux-user: Implement x86_64 vsyscalls Richard Henderson
2020-01-14 21:09 ` [PATCH 1/3] target/i386: Renumber EXCP_SYSCALL Richard Henderson
2020-01-14 21:09 ` [PATCH 2/3] linux-user/i386: Split out gen_signal Richard Henderson
@ 2020-01-14 21:09 ` Richard Henderson
2020-01-16 10:51 ` Alex Bennée
2020-01-16 16:26 ` Alex Bennée
2020-01-14 23:35 ` [PATCH 0/3] linux-user: Implement " Paolo Bonzini
` (4 subsequent siblings)
7 siblings, 2 replies; 21+ messages in thread
From: Richard Henderson @ 2020-01-14 21:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini, riku.voipio, laurent, peter.maydell
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.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/cpu.h | 1 +
linux-user/i386/cpu_loop.c | 104 +++++++++++++++++++++++++++++++++++++
target/i386/translate.c | 16 +++++-
3 files changed, 120 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..8b7c9f7337 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -92,6 +92,105 @@ 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;
+ }
+
+ 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:
+ /* Like force_sig(SIGSEGV). */
+ gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
+ return;
+ }
+
+ /*
+ * Validate the return address.
+ * Note that the kernel treats this the same as an invalid entry point.
+ */
+ if (get_user_u64(caller, env->regs[R_ESP])) {
+ goto sigsegv;
+ }
+
+ /*
+ * Validate the the pointer arguments.
+ */
+ switch (syscall) {
+ case TARGET_NR_gettimeofday:
+ if (!write_ok_or_segv(env, env->regs[R_EDI],
+ sizeof(struct target_timeval)) ||
+ !write_ok_or_segv(env, env->regs[R_ESI],
+ sizeof(struct target_timezone))) {
+ return;
+ }
+ break;
+ case TARGET_NR_time:
+ if (!write_ok_or_segv(env, env->regs[R_EDI], sizeof(abi_long))) {
+ return;
+ }
+ break;
+ case TARGET_NR_getcpu:
+ if (!write_ok_or_segv(env, env->regs[R_EDI], sizeof(uint32_t)) ||
+ !write_ok_or_segv(env, env->regs[R_ESI], sizeof(uint32_t))) {
+ return;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ /*
+ * Perform the syscall. None of the vsyscalls should need restarting,
+ * and all faults should have been caught above.
+ */
+ ret = do_syscall(env, syscall, env->regs[R_EDI], env->regs[R_ESI],
+ env->regs[R_EDX], env->regs[10], env->regs[8],
+ env->regs[9], 0, 0);
+ g_assert(ret != -TARGET_ERESTARTSYS);
+ g_assert(ret != -TARGET_QEMU_ESIGRETURN);
+ g_assert(ret != -TARGET_EFAULT);
+ env->regs[R_EAX] = ret;
+
+ /* Emulate a ret instruction to leave the vsyscall page. */
+ env->eip = caller;
+ env->regs[R_ESP] += 8;
+}
+#endif
+
void cpu_loop(CPUX86State *env)
{
CPUState *cs = env_cpu(env);
@@ -141,6 +240,11 @@ void cpu_loop(CPUX86State *env)
env->regs[R_EAX] = ret;
}
break;
+#endif
+#ifdef TARGET_X86_64
+ case EXCP_VSYSCALL:
+ emulate_vsyscall(env);
+ break;
#endif
case EXCP0B_NOSEG:
case EXCP0C_STACK:
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 7c99ef1385..391b4ef149 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -8555,7 +8555,21 @@ static bool i386_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
- target_ulong pc_next = disas_insn(dc, cpu);
+ target_ulong pc_next;
+
+#if defined(TARGET_X86_64) && \
+ defined(CONFIG_USER_ONLY) && \
+ defined(CONFIG_LINUX)
+ /*
+ * Detect entry into the vsyscall page and invoke the syscall.
+ */
+ if ((dc->base.pc_next & TARGET_PAGE_MASK) == 0xffffffffff600000ull) {
+ gen_exception(dc, EXCP_VSYSCALL, dc->base.pc_next);
+ return;
+ }
+#endif
+
+ pc_next = disas_insn(dc, cpu);
if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
/* if single step mode, we generate only one instruction and
--
2.20.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls
2020-01-14 21:09 ` [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls Richard Henderson
@ 2020-01-16 10:51 ` Alex Bennée
2020-01-16 16:26 ` Alex Bennée
1 sibling, 0 replies; 21+ messages in thread
From: Alex Bennée @ 2020-01-16 10:51 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
Richard Henderson <richard.henderson@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.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
So I've been trying to test this but have run into a number of
(unrelated) hurdles on the way on my system. I think I've eliminated
these patches but it might be a regression.
Does running /sbin/ldconfig work ok for you?
--
Alex Bennée
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls
2020-01-14 21:09 ` [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls Richard Henderson
2020-01-16 10:51 ` Alex Bennée
@ 2020-01-16 16:26 ` Alex Bennée
2020-01-16 18:19 ` Richard Henderson
1 sibling, 1 reply; 21+ messages in thread
From: Alex Bennée @ 2020-01-16 16:26 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
Richard Henderson <richard.henderson@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.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/cpu.h | 1 +
> linux-user/i386/cpu_loop.c | 104 +++++++++++++++++++++++++++++++++++++
> target/i386/translate.c | 16 +++++-
> 3 files changed, 120 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..8b7c9f7337 100644
> --- a/linux-user/i386/cpu_loop.c
> +++ b/linux-user/i386/cpu_loop.c
> @@ -92,6 +92,105 @@ 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;
> + }
> +
> + 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:
> + /* Like force_sig(SIGSEGV). */
> + gen_signal(env, TARGET_SIGSEGV, TARGET_SI_KERNEL, 0);
> + return;
> + }
> +
> + /*
> + * Validate the return address.
> + * Note that the kernel treats this the same as an invalid entry point.
> + */
> + if (get_user_u64(caller, env->regs[R_ESP])) {
> + goto sigsegv;
> + }
> +
> + /*
> + * Validate the the pointer arguments.
> + */
> + switch (syscall) {
> + case TARGET_NR_gettimeofday:
> + if (!write_ok_or_segv(env, env->regs[R_EDI],
> + sizeof(struct target_timeval)) ||
> + !write_ok_or_segv(env, env->regs[R_ESI],
> + sizeof(struct target_timezone))) {
> + return;
> + }
> + break;
> + case TARGET_NR_time:
> + if (!write_ok_or_segv(env, env->regs[R_EDI], sizeof(abi_long))) {
> + return;
> + }
> + break;
> + case TARGET_NR_getcpu:
> + if (!write_ok_or_segv(env, env->regs[R_EDI], sizeof(uint32_t)) ||
> + !write_ok_or_segv(env, env->regs[R_ESI], sizeof(uint32_t))) {
> + return;
> + }
> + break;
> + default:
> + g_assert_not_reached();
> + }
> +
> + /*
> + * Perform the syscall. None of the vsyscalls should need restarting,
> + * and all faults should have been caught above.
> + */
> + ret = do_syscall(env, syscall, env->regs[R_EDI], env->regs[R_ESI],
> + env->regs[R_EDX], env->regs[10], env->regs[8],
> + env->regs[9], 0, 0);
How come the register ABI to the syscall is different to the others. I
can see why syscall doesn't come from EAX but the others are a different
set to normal syscalls which might be why:
> + g_assert(ret != -TARGET_ERESTARTSYS);
> + g_assert(ret != -TARGET_QEMU_ESIGRETURN);
> + g_assert(ret != -TARGET_EFAULT);
I'm seeing a EFAULT on the gettimeofday failure:
#0 do_syscall (cpu_env=cpu_env@entry=0x5555577d2b10, num=num@entry=96, arg1=0, arg2=0, arg3=4211016, arg4=8, arg5=274888677184, arg6=274886295415, arg7=0, arg8=0) at /home/alex/lsrc/qemu.git/linux-user/syscall.c:12076
#1 0x0000555555609b6e in emulate_vsyscall (env=0x5555577d2b10) at /home/alex/lsrc/qemu.git/linux-user/x86_64/../i386/cpu_loop.c:180
#2 cpu_loop (env=0x5555577d2b10) at /home/alex/lsrc/qemu.git/linux-user/x86_64/../i386/cpu_loop.c:246
#3 0x000055555559640e in main (argc=<optimized out>, argv=<optimized
#out>, envp=<optimized out>) at
#/home/alex/lsrc/qemu.git/linux-user/main.c:865
arg1/arg2 don't seem right here.
> + env->regs[R_EAX] = ret;
> +
> + /* Emulate a ret instruction to leave the vsyscall page. */
> + env->eip = caller;
> + env->regs[R_ESP] += 8;
> +}
> +#endif
> +
> void cpu_loop(CPUX86State *env)
> {
> CPUState *cs = env_cpu(env);
> @@ -141,6 +240,11 @@ void cpu_loop(CPUX86State *env)
> env->regs[R_EAX] = ret;
> }
> break;
> +#endif
> +#ifdef TARGET_X86_64
> + case EXCP_VSYSCALL:
> + emulate_vsyscall(env);
> + break;
> #endif
> case EXCP0B_NOSEG:
> case EXCP0C_STACK:
> diff --git a/target/i386/translate.c b/target/i386/translate.c
> index 7c99ef1385..391b4ef149 100644
> --- a/target/i386/translate.c
> +++ b/target/i386/translate.c
> @@ -8555,7 +8555,21 @@ static bool i386_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
> static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
> {
> DisasContext *dc = container_of(dcbase, DisasContext, base);
> - target_ulong pc_next = disas_insn(dc, cpu);
> + target_ulong pc_next;
> +
> +#if defined(TARGET_X86_64) && \
> + defined(CONFIG_USER_ONLY) && \
> + defined(CONFIG_LINUX)
> + /*
> + * Detect entry into the vsyscall page and invoke the syscall.
> + */
> + if ((dc->base.pc_next & TARGET_PAGE_MASK) == 0xffffffffff600000ull) {
> + gen_exception(dc, EXCP_VSYSCALL, dc->base.pc_next);
> + return;
> + }
> +#endif
> +
> + pc_next = disas_insn(dc, cpu);
>
> if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
> /* if single step mode, we generate only one instruction and
--
Alex Bennée
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls
2020-01-16 16:26 ` Alex Bennée
@ 2020-01-16 18:19 ` Richard Henderson
2020-01-16 18:22 ` Richard Henderson
2020-01-16 20:15 ` Alex Bennée
0 siblings, 2 replies; 21+ messages in thread
From: Richard Henderson @ 2020-01-16 18:19 UTC (permalink / raw)
To: Alex Bennée
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
On 1/16/20 6:26 AM, Alex Bennée wrote:
>> + /*
>> + * Perform the syscall. None of the vsyscalls should need restarting,
>> + * and all faults should have been caught above.
>> + */
>> + ret = do_syscall(env, syscall, env->regs[R_EDI], env->regs[R_ESI],
>> + env->regs[R_EDX], env->regs[10], env->regs[8],
>> + env->regs[9], 0, 0);
>
> How come the register ABI to the syscall is different to the others. I
> can see why syscall doesn't come from EAX but the others are a different
> set to normal syscalls which might be why:
Cut and paste error, I assume.
That said, the three syscalls have a maximum of 2 arguments,
so I could really just pass EDI and ESI and 0 for the rest...
> I'm seeing a EFAULT on the gettimeofday failure:
What getttimeofday failure? Is this related to the mention of /sbin/ldconfig
in your previous message?
> #0 do_syscall (cpu_env=cpu_env@entry=0x5555577d2b10, num=num@entry=96, arg1=0, arg2=0, arg3=4211016, arg4=8, arg5=274888677184, arg6=274886295415, arg7=0, arg8=0) at /home/alex/lsrc/qemu.git/linux-user/syscall.c:12076
> #1 0x0000555555609b6e in emulate_vsyscall (env=0x5555577d2b10) at /home/alex/lsrc/qemu.git/linux-user/x86_64/../i386/cpu_loop.c:180
> #2 cpu_loop (env=0x5555577d2b10) at /home/alex/lsrc/qemu.git/linux-user/x86_64/../i386/cpu_loop.c:246
> #3 0x000055555559640e in main (argc=<optimized out>, argv=<optimized
> #out>, envp=<optimized out>) at
> #/home/alex/lsrc/qemu.git/linux-user/main.c:865
>
> arg1/arg2 don't seem right here.
Why? NULL value for arg1 is legal, though semi-useless.
Ah, I see that our implementation of gettimeofday doesn't honor NULL.
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls
2020-01-16 18:19 ` Richard Henderson
@ 2020-01-16 18:22 ` Richard Henderson
2020-01-16 20:15 ` Alex Bennée
1 sibling, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2020-01-16 18:22 UTC (permalink / raw)
To: Alex Bennée
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
On 1/16/20 8:19 AM, Richard Henderson wrote:
> On 1/16/20 6:26 AM, Alex Bennée wrote:
>>> + /*
>>> + * Perform the syscall. None of the vsyscalls should need restarting,
>>> + * and all faults should have been caught above.
>>> + */
>>> + ret = do_syscall(env, syscall, env->regs[R_EDI], env->regs[R_ESI],
>>> + env->regs[R_EDX], env->regs[10], env->regs[8],
>>> + env->regs[9], 0, 0);
>>
>> How come the register ABI to the syscall is different to the others. I
>> can see why syscall doesn't come from EAX but the others are a different
>> set to normal syscalls which might be why:
>
> Cut and paste error, I assume.
What register difference?
case EXCP_SYSCALL:
/* linux syscall from syscall instruction */
ret = do_syscall(env,
env->regs[R_EAX],
env->regs[R_EDI],
env->regs[R_ESI],
env->regs[R_EDX],
env->regs[10],
env->regs[8],
env->regs[9],
0, 0);
Looks the same to me...
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls
2020-01-16 18:19 ` Richard Henderson
2020-01-16 18:22 ` Richard Henderson
@ 2020-01-16 20:15 ` Alex Bennée
1 sibling, 0 replies; 21+ messages in thread
From: Alex Bennée @ 2020-01-16 20:15 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
Richard Henderson <richard.henderson@linaro.org> writes:
> On 1/16/20 6:26 AM, Alex Bennée wrote:
>>> + /*
>>> + * Perform the syscall. None of the vsyscalls should need restarting,
>>> + * and all faults should have been caught above.
>>> + */
>>> + ret = do_syscall(env, syscall, env->regs[R_EDI], env->regs[R_ESI],
>>> + env->regs[R_EDX], env->regs[10], env->regs[8],
>>> + env->regs[9], 0, 0);
>>
>> How come the register ABI to the syscall is different to the others. I
>> can see why syscall doesn't come from EAX but the others are a different
>> set to normal syscalls which might be why:
>
> Cut and paste error, I assume.
>
> That said, the three syscalls have a maximum of 2 arguments,
> so I could really just pass EDI and ESI and 0 for the rest...
>
>> I'm seeing a EFAULT on the gettimeofday failure:
>
> What getttimeofday failure? Is this related to the mention of /sbin/ldconfig
> in your previous message?
No - the buster x86064 ldconfig seg is unrelated to this series. It has
however spawned an additional bug in gdbstub while it was at it ;-)
>
>> #0 do_syscall (cpu_env=cpu_env@entry=0x5555577d2b10, num=num@entry=96, arg1=0, arg2=0, arg3=4211016, arg4=8, arg5=274888677184, arg6=274886295415, arg7=0, arg8=0) at /home/alex/lsrc/qemu.git/linux-user/syscall.c:12076
>> #1 0x0000555555609b6e in emulate_vsyscall (env=0x5555577d2b10) at /home/alex/lsrc/qemu.git/linux-user/x86_64/../i386/cpu_loop.c:180
>> #2 cpu_loop (env=0x5555577d2b10) at /home/alex/lsrc/qemu.git/linux-user/x86_64/../i386/cpu_loop.c:246
>> #3 0x000055555559640e in main (argc=<optimized out>, argv=<optimized
>> #out>, envp=<optimized out>) at
>> #/home/alex/lsrc/qemu.git/linux-user/main.c:865
>>
>> arg1/arg2 don't seem right here.
>
> Why? NULL value for arg1 is legal, though semi-useless.
>
> Ah, I see that our implementation of gettimeofday doesn't honor NULL.
>
>
> r~
--
Alex Bennée
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] linux-user: Implement x86_64 vsyscalls
2020-01-14 21:09 [PATCH 0/3] linux-user: Implement x86_64 vsyscalls Richard Henderson
` (2 preceding siblings ...)
2020-01-14 21:09 ` [PATCH 3/3] linux-user/i386: Emulate x86_64 vsyscalls Richard Henderson
@ 2020-01-14 23:35 ` Paolo Bonzini
2020-01-15 7:01 ` Laurent Desnogues
` (3 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2020-01-14 23:35 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: peter.maydell, riku.voipio, laurent
On 14/01/20 22:09, Richard Henderson wrote:
> I vaguely remember someone (Paolo?) implementing something like
> this many years ago, but clearly it never got merged.
Nope, certainly not me.
> In any case, this emulation has been missing for too long.
>
>
> r~
>
>
> Richard Henderson (3):
> target/i386: Renumber EXCP_SYSCALL
> linux-user/i386: Split out gen_signal
> linux-user/i386: Emulate x86_64 vsyscalls
>
> target/i386/cpu.h | 6 +-
> linux-user/i386/cpu_loop.c | 197 ++++++++++++++++++++++++++-----------
> target/i386/translate.c | 16 ++-
> 3 files changed, 155 insertions(+), 64 deletions(-)
>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] linux-user: Implement x86_64 vsyscalls
2020-01-14 21:09 [PATCH 0/3] linux-user: Implement x86_64 vsyscalls Richard Henderson
` (3 preceding siblings ...)
2020-01-14 23:35 ` [PATCH 0/3] linux-user: Implement " Paolo Bonzini
@ 2020-01-15 7:01 ` Laurent Desnogues
2020-01-15 10:14 ` Laurent Vivier
` (2 subsequent siblings)
7 siblings, 0 replies; 21+ messages in thread
From: Laurent Desnogues @ 2020-01-15 7:01 UTC (permalink / raw)
To: Richard Henderson
Cc: Peter Maydell, Paolo Bonzini, Riku Voipio, qemu-devel, Laurent Vivier
On Tue, Jan 14, 2020 at 10:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
[...]
> I vaguely remember someone (Paolo?) implementing something like
> this many years ago, but clearly it never got merged.
That was me back in 2009:
https://lists.gnu.org/archive/html/qemu-devel/2009-07/msg00881.html
Glad it will finally get an official fix.
Thanks,
Laurent
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] linux-user: Implement x86_64 vsyscalls
2020-01-14 21:09 [PATCH 0/3] linux-user: Implement x86_64 vsyscalls Richard Henderson
` (4 preceding siblings ...)
2020-01-15 7:01 ` Laurent Desnogues
@ 2020-01-15 10:14 ` Laurent Vivier
2020-01-15 17:28 ` Richard Henderson
2020-01-16 14:05 ` Alex Bennée
2020-01-16 14:30 ` Alex Bennée
7 siblings, 1 reply; 21+ messages in thread
From: Laurent Vivier @ 2020-01-15 10:14 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: pbonzini, riku.voipio, peter.maydell
Le 14/01/2020 à 22:09, Richard Henderson a écrit :
> The x86_64 abi has a legacy vsyscall page. The kernel folk
> have been trying to deprecate this since at least v3.1, but
>
> (1) We don't implement the vdso that replaces vsyscalls,
> (2) As of v5.5, the vsyscall page is still enabled by default.
>
> This lack is affecting Peter's linux-user testing.
>
> The dependency is not obvious because Peter is running the tests
> on x86_64, so the host is providing a vsyscall page to qemu.
>
> Because of how user-only memory operations are handled, with no
> validation of guest vs host pages, so long as qemu chooses to
> run with guest_base == 0, the guest may Just So Happen to read
> the host's vsyscall page.
>
> Complicating this, new OS releases may use a kernel configured
> with CONFIG_LEGACY_VSYSCALL_XONLY=y, which means the the vsyscall
> page cannot be read, only executed. Which means that the guest
> then cannot read the host vsyscall page during translation and
> will SIGSEGV.
>
> Exactly which of these many variables is affecting Peter's testing
> with Ubuntu 18.04 of my TCG merge, I'm not exactly sure. I suspect
> that it is the change to drop the textseg_addr adjustment to user-only
> static binaries. IIRC bionic does not support -static-pie, which is
> the preferred replacement. This could mean that the host and guest
> binaries overlap, which leads to guest_base != 0.
>
> I vaguely remember someone (Paolo?) implementing something like
> this many years ago, but clearly it never got merged.
>
> In any case, this emulation has been missing for too long.
>
>
> r~
>
>
> Richard Henderson (3):
> target/i386: Renumber EXCP_SYSCALL
> linux-user/i386: Split out gen_signal
> linux-user/i386: Emulate x86_64 vsyscalls
>
> target/i386/cpu.h | 6 +-
> linux-user/i386/cpu_loop.c | 197 ++++++++++++++++++++++++++-----------
> target/i386/translate.c | 16 ++-
> 3 files changed, 155 insertions(+), 64 deletions(-)
>
Thank you Richard.
I'll take this series through the linux-user branch except if you prefer
to do the pull request yourself via another branch (x86 tcg?).
Thanks,
Laurent
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] linux-user: Implement x86_64 vsyscalls
2020-01-15 10:14 ` Laurent Vivier
@ 2020-01-15 17:28 ` Richard Henderson
0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2020-01-15 17:28 UTC (permalink / raw)
To: Laurent Vivier, qemu-devel; +Cc: pbonzini, riku.voipio, peter.maydell
On 1/15/20 12:14 AM, Laurent Vivier wrote:
> I'll take this series through the linux-user branch except if you prefer
> to do the pull request yourself via another branch (x86 tcg?).
Through the linux-user branch is the right way, I think.
Thanks,
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] linux-user: Implement x86_64 vsyscalls
2020-01-14 21:09 [PATCH 0/3] linux-user: Implement x86_64 vsyscalls Richard Henderson
` (5 preceding siblings ...)
2020-01-15 10:14 ` Laurent Vivier
@ 2020-01-16 14:05 ` Alex Bennée
2020-01-16 19:37 ` Richard Henderson
2020-01-16 14:30 ` Alex Bennée
7 siblings, 1 reply; 21+ messages in thread
From: Alex Bennée @ 2020-01-16 14:05 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
Richard Henderson <richard.henderson@linaro.org> writes:
> The x86_64 abi has a legacy vsyscall page. The kernel folk
> have been trying to deprecate this since at least v3.1, but
>
> (1) We don't implement the vdso that replaces vsyscalls,
> (2) As of v5.5, the vsyscall page is still enabled by default.
>
> This lack is affecting Peter's linux-user testing.
>
> The dependency is not obvious because Peter is running the tests
> on x86_64, so the host is providing a vsyscall page to qemu.
>
> Because of how user-only memory operations are handled, with no
> validation of guest vs host pages, so long as qemu chooses to
> run with guest_base == 0, the guest may Just So Happen to read
> the host's vsyscall page.
>
> Complicating this, new OS releases may use a kernel configured
> with CONFIG_LEGACY_VSYSCALL_XONLY=y, which means the the vsyscall
> page cannot be read, only executed. Which means that the guest
> then cannot read the host vsyscall page during translation and
> will SIGSEGV.
>
> Exactly which of these many variables is affecting Peter's testing
> with Ubuntu 18.04 of my TCG merge, I'm not exactly sure. I suspect
> that it is the change to drop the textseg_addr adjustment to user-only
> static binaries. IIRC bionic does not support -static-pie, which is
> the preferred replacement. This could mean that the host and guest
> binaries overlap, which leads to guest_base != 0.
>
> I vaguely remember someone (Paolo?) implementing something like
> this many years ago, but clearly it never got merged.
>
> In any case, this emulation has been missing for too long.
It turns out the /sbin/ldconfig crash is a regression w.r.t from
stretch->buster so unrelated to these patches. However I've been giving
them a spin with the linux vdso selftests and stuff is breaking which I
guess means it's incomplete?
alex@23eb55f27ff8:~/lsrc/linux.git/tools/testing/selftests/x86$ make test_vdso
gcc -m64 -o /home/alex/lsrc/linux.git/tools/testing/selftests/x86/test_vdso_64 -O2 -g -std=gnu99 -pthread -Wall -no-pie -DCAN_BUILD_64 test_vdso.c -lrt -ldl
alex@23eb55f27ff8:~/lsrc/linux.git/tools/testing/selftests/x86$ ./test_vdso_64
[WARN] failed to find vDSO
[RUN] Testing clock_gettime for clock CLOCK_REALTIME (0)...
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault (core dumped)
Also from selftests/vDSO:
alex@23eb55f27ff8:~/lsrc/linux.git/tools/testing/selftests/vDSO$ ./vdso_test
AT_SYSINFO_EHDR is not present!
vdso_standalone_test_x86 just exits with a non-zero value. I'm still
looking into that one.
>
>
> r~
>
>
> Richard Henderson (3):
> target/i386: Renumber EXCP_SYSCALL
> linux-user/i386: Split out gen_signal
> linux-user/i386: Emulate x86_64 vsyscalls
>
> target/i386/cpu.h | 6 +-
> linux-user/i386/cpu_loop.c | 197 ++++++++++++++++++++++++++-----------
> target/i386/translate.c | 16 ++-
> 3 files changed, 155 insertions(+), 64 deletions(-)
--
Alex Bennée
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] linux-user: Implement x86_64 vsyscalls
2020-01-16 14:05 ` Alex Bennée
@ 2020-01-16 19:37 ` Richard Henderson
0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2020-01-16 19:37 UTC (permalink / raw)
To: Alex Bennée
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
On 1/16/20 4:05 AM, Alex Bennée wrote:
> It turns out the /sbin/ldconfig crash is a regression w.r.t from
> stretch->buster so unrelated to these patches. However I've been giving
> them a spin with the linux vdso selftests and stuff is breaking which I
> guess means it's incomplete?
...
> Also from selftests/vDSO:
>
> alex@23eb55f27ff8:~/lsrc/linux.git/tools/testing/selftests/vDSO$ ./vdso_test
> AT_SYSINFO_EHDR is not present!
This patch set is for vsyscall only, not vdso.
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] linux-user: Implement x86_64 vsyscalls
2020-01-14 21:09 [PATCH 0/3] linux-user: Implement x86_64 vsyscalls Richard Henderson
` (6 preceding siblings ...)
2020-01-16 14:05 ` Alex Bennée
@ 2020-01-16 14:30 ` Alex Bennée
2020-01-16 18:31 ` Richard Henderson
7 siblings, 1 reply; 21+ messages in thread
From: Alex Bennée @ 2020-01-16 14:30 UTC (permalink / raw)
To: Richard Henderson
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
Richard Henderson <richard.henderson@linaro.org> writes:
> The x86_64 abi has a legacy vsyscall page. The kernel folk
> have been trying to deprecate this since at least v3.1, but
>
> (1) We don't implement the vdso that replaces vsyscalls,
> (2) As of v5.5, the vsyscall page is still enabled by default.
>
> This lack is affecting Peter's linux-user testing.
>
> The dependency is not obvious because Peter is running the tests
> on x86_64, so the host is providing a vsyscall page to qemu.
>
> Because of how user-only memory operations are handled, with no
> validation of guest vs host pages, so long as qemu chooses to
> run with guest_base == 0, the guest may Just So Happen to read
> the host's vsyscall page.
>
> Complicating this, new OS releases may use a kernel configured
> with CONFIG_LEGACY_VSYSCALL_XONLY=y, which means the the vsyscall
> page cannot be read, only executed. Which means that the guest
> then cannot read the host vsyscall page during translation and
> will SIGSEGV.
>
> Exactly which of these many variables is affecting Peter's testing
> with Ubuntu 18.04 of my TCG merge, I'm not exactly sure. I suspect
> that it is the change to drop the textseg_addr adjustment to user-only
> static binaries. IIRC bionic does not support -static-pie, which is
> the preferred replacement. This could mean that the host and guest
> binaries overlap, which leads to guest_base != 0.
>
> I vaguely remember someone (Paolo?) implementing something like
> this many years ago, but clearly it never got merged.
>
> In any case, this emulation has been missing for too long.
>
>
> r~
>
>
> Richard Henderson (3):
> target/i386: Renumber EXCP_SYSCALL
> linux-user/i386: Split out gen_signal
> linux-user/i386: Emulate x86_64 vsyscalls
And realising I didn't read it properly:
/x86_64-linux-user/qemu-x86_64 ~/lsrc/linux.git/tools/testing/selftests/x86/test_vsyscall_64
[WARN] failed to find vDSO
no vsyscall map in /proc/self/maps
[RUN] test gettimeofday()
[RUN] test time()
[RUN] getcpu() on CPU 0
[RUN] getcpu() on CPU 1
[RUN] Checking read access to the vsyscall page
[OK] We do not have read access: #PF(0x4)
[RUN] Make sure that vsyscalls really page fault
**
ERROR:/home/alex/lsrc/qemu.git/linux-user/x86_64/../i386/cpu_loop.c:185:emulate_vsyscall: assertion failed: (ret != -TARGET_EFAULT)
qemu:handle_cpu_signal received signal outside vCPU context @ pc=0x7f6eed31b613
--
Alex Bennée
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/3] linux-user: Implement x86_64 vsyscalls
2020-01-16 14:30 ` Alex Bennée
@ 2020-01-16 18:31 ` Richard Henderson
0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2020-01-16 18:31 UTC (permalink / raw)
To: Alex Bennée
Cc: qemu-devel, pbonzini, riku.voipio, laurent, peter.maydell
On 1/16/20 4:30 AM, Alex Bennée wrote:
> /x86_64-linux-user/qemu-x86_64 ~/lsrc/linux.git/tools/testing/selftests/x86/test_vsyscall_64
> [WARN] failed to find vDSO
> no vsyscall map in /proc/self/maps
> [RUN] test gettimeofday()
> [RUN] test time()
> [RUN] getcpu() on CPU 0
> [RUN] getcpu() on CPU 1
> [RUN] Checking read access to the vsyscall page
> [OK] We do not have read access: #PF(0x4)
> [RUN] Make sure that vsyscalls really page fault
> **
> ERROR:/home/alex/lsrc/qemu.git/linux-user/x86_64/../i386/cpu_loop.c:185:emulate_vsyscall: assertion failed: (ret != -TARGET_EFAULT)
> qemu:handle_cpu_signal received signal outside vCPU context @ pc=0x7f6eed31b613
Ok, thanks.
r~
^ permalink raw reply [flat|nested] 21+ messages in thread