From bd4b7fd6ba98e2d660356f1f52edcec5c51b0991 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 18 Jul 2022 18:40:43 +0200 Subject: [PATCH 1/3] linux-user/hppa: Fix segfaults on page zero This program: int main(void) { asm("bv %r0(%r0)"); return 0; } produces on real hppa hardware the expected segfault: SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x3} --- killed by SIGSEGV +++ Segmentation fault But when run on linux-user you get instead internal qemu errors: ERROR: linux-user/hppa/cpu_loop.c:172:cpu_loop: code should not be reached Bail out! ERROR: linux-user/hppa/cpu_loop.c:172:cpu_loop: code should not be reached ERROR: accel/tcg/cpu-exec.c:933:cpu_exec: assertion failed: (cpu == current_cpu) Bail out! ERROR: accel/tcg/cpu-exec.c:933:cpu_exec: assertion failed: (cpu == current_cpu) Fix it by adding the missing case for the EXCP_IMP trap in cpu_loop() and raise a segfault. Signed-off-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: Signed-off-by: Laurent Vivier --- linux-user/hppa/cpu_loop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c index a576d1a249..64263c3dc4 100644 --- a/linux-user/hppa/cpu_loop.c +++ b/linux-user/hppa/cpu_loop.c @@ -143,6 +143,9 @@ void cpu_loop(CPUHPPAState *env) env->iaoq_f = env->gr[31]; env->iaoq_b = env->gr[31] + 4; break; + case EXCP_IMP: + force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->iaoq_f); + break; case EXCP_ILL: force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPN, env->iaoq_f); break; From 499d8055379f5beb2ca155c668eca52b8a24321a Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 19 Jul 2022 18:20:42 +0200 Subject: [PATCH 2/3] linux-user: Unconditionally use pipe2() syscall The pipe2() syscall is available on all Linux platforms since kernel 2.6.27, so use it unconditionally to emulate pipe() and pipe2(). Signed-off-by: Helge Deller Reviewed-by: Peter Maydell Message-Id: Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 11 +---------- meson.build | 9 --------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 991b85e6b4..4f89184d05 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1586,21 +1586,12 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3, } #endif -static abi_long do_pipe2(int host_pipe[], int flags) -{ -#ifdef CONFIG_PIPE2 - return pipe2(host_pipe, flags); -#else - return -ENOSYS; -#endif -} - static abi_long do_pipe(CPUArchState *cpu_env, abi_ulong pipedes, int flags, int is_pipe2) { int host_pipe[2]; abi_long ret; - ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe); + ret = pipe2(host_pipe, flags); if (is_error(ret)) return get_errno(ret); diff --git a/meson.build b/meson.build index 8a8c415fc1..75aaca8462 100644 --- a/meson.build +++ b/meson.build @@ -2026,15 +2026,6 @@ config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + ''' #else int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } #endif''')) -config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + ''' - #include - #include - - int main(void) - { - int pipefd[2]; - return pipe2(pipefd, O_CLOEXEC); - }''')) config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + ''' #include #include From 6f200f51869ff0de7ea0343dd7104362e994b382 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 17 Jul 2022 18:21:53 +0200 Subject: [PATCH 3/3] linux-user: Use target abi_int type for pipefd[1] in pipe() When writing back the fd[1] pipe file handle to emulated userspace memory, use sizeof(abi_int) as offset insted of the hosts's int type. There is no functional change in this patch. Signed-off-by: Helge Deller Reviewed-by: Richard Henderson Message-Id: Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 4f89184d05..b27a6552aa 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1615,7 +1615,7 @@ static abi_long do_pipe(CPUArchState *cpu_env, abi_ulong pipedes, } if (put_user_s32(host_pipe[0], pipedes) - || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) + || put_user_s32(host_pipe[1], pipedes + sizeof(abi_int))) return -TARGET_EFAULT; return get_errno(ret); }