From ab546bd23856866411ff1b2ffaedabdc360e69df Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 20 Apr 2020 22:22:05 +0100 Subject: [PATCH] linux-user/arm: Handle invalid arm-specific syscalls correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The kernel has different handling for syscalls with invalid numbers that are in the "arm-specific" range 0x9f0000 and up: * 0x9f0000..0x9f07ff return -ENOSYS if not implemented * other out of range syscalls cause a SIGILL (see the kernel's arch/arm/kernel/traps.c:arm_syscall()) Implement this distinction. (Note that our code doesn't look quite like the kernel's, because we have removed the 0x900000 prefix by this point, whereas the kernel retains it in arm_syscall().) Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-id: 20200420212206.12776-4-peter.maydell@linaro.org --- linux-user/arm/cpu_loop.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c index 025887d6b8..df8b7b3fa9 100644 --- a/linux-user/arm/cpu_loop.c +++ b/linux-user/arm/cpu_loop.c @@ -332,10 +332,32 @@ void cpu_loop(CPUARMState *env) env->regs[0] = cpu_get_tls(env); break; default: - qemu_log_mask(LOG_UNIMP, - "qemu: Unsupported ARM syscall: 0x%x\n", - n); - env->regs[0] = -TARGET_ENOSYS; + if (n < 0xf0800) { + /* + * Syscalls 0xf0000..0xf07ff (or 0x9f0000.. + * 0x9f07ff in OABI numbering) are defined + * to return -ENOSYS rather than raising + * SIGILL. Note that we have already + * removed the 0x900000 prefix. + */ + qemu_log_mask(LOG_UNIMP, + "qemu: Unsupported ARM syscall: 0x%x\n", + n); + env->regs[0] = -TARGET_ENOSYS; + } else { + /* Otherwise SIGILL */ + info.si_signo = TARGET_SIGILL; + info.si_errno = 0; + info.si_code = TARGET_ILL_ILLTRP; + info._sifields._sigfault._addr = env->regs[15]; + if (env->thumb) { + info._sifields._sigfault._addr -= 2; + } else { + info._sifields._sigfault._addr -= 4; + } + queue_signal(env, info.si_signo, + QEMU_SI_FAULT, &info); + } break; } } else {