From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Cwi2N-0003IZ-C2 for qemu-devel@nongnu.org; Thu, 03 Feb 2005 09:32:52 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Cwi27-00039y-W6 for qemu-devel@nongnu.org; Thu, 03 Feb 2005 09:32:36 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Cwi27-00034U-Pi for qemu-devel@nongnu.org; Thu, 03 Feb 2005 09:32:35 -0500 Received: from [195.135.220.2] (helo=Cantor.suse.de) by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.34) id 1CwhfN-0003lC-OX for qemu-devel@nongnu.org; Thu, 03 Feb 2005 09:09:06 -0500 Received: from hermes.suse.de (hermes-ext.suse.de [195.135.221.8]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by Cantor.suse.de (Postfix) with ESMTP id 49A8A13FB9DC for ; Thu, 3 Feb 2005 15:09:04 +0100 (CET) From: Ulrich Hecht Subject: Re: [Qemu-devel] Armv5 target Date: Thu, 3 Feb 2005 15:08:59 +0100 References: <200501312019.45282.paul@codesourcery.com> <200502021918.47411.uli@suse.de> <200502021917.02193.paul@codesourcery.com> In-Reply-To: <200502021917.02193.paul@codesourcery.com> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_7BjACkxbwagc5fc" Message-Id: <200502031508.59501.uli@suse.de> Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --Boundary-00=_7BjACkxbwagc5fc Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi! On Wednesday 02 February 2005 20:17, Paul Brook wrote: > The generated code causes a segfault trying to write to protected > memory. On a real machine the signal handler unprotects the memory, > and keeps going. Inside qemu the host signal handler just queues the > target signal. For most signals this is ok; the target handler will be > invoke at the end of the TB. However in this case we need to run the > target handler immediately, otherwise the segv will occur again when > we try and continue. > > I think fixing this requires executing the target signal handler code > from within the host signal handler. As an added complication we only > want to do this for signals received while executing target code. Copying some code from the i386 and SPARC targets, I made up the attached patch. It fixes the segv_test testcase (and my personal use case, the GCC 3.3 configure script), and it does not seem to break anything else. Comments? CU Uli --Boundary-00=_7BjACkxbwagc5fc Content-Type: text/x-diff; charset="utf-8"; name="qemu-arm-signals.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qemu-arm-signals.patch" Index: cpu-exec.c =================================================================== RCS file: /cvsroot/qemu/qemu/cpu-exec.c,v retrieving revision 1.46 diff -u -r1.46 cpu-exec.c --- cpu-exec.c 2 Feb 2005 20:42:01 -0000 1.46 +++ cpu-exec.c 3 Feb 2005 14:04:53 -0000 @@ -731,11 +731,35 @@ int is_write, sigset_t *old_set, void *puc) { + TranslationBlock *tb; + + if (cpu_single_env) + env = cpu_single_env; /* XXX: find a correct solution for multithread */ +#if defined(DEBUG_SIGNAL) + qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", + pc, address, is_write, *(unsigned long *)old_set); +#endif /* XXX: locking issue */ if (is_write && page_unprotect(address, pc, puc)) { return 1; } - return 0; + + /* XXX: see if it is an MMU fault */ + env->address=address; + tb = tb_find_pc(pc); + if (tb) { + /* the PC is inside the translated code. It means that we have + a virtual CPU fault */ + cpu_restore_state(tb, env, pc, puc); + } + + /* we restore the process signal mask as the sigreturn should + do it (XXX: use sigsetjmp) */ + sigprocmask(SIG_SETMASK, old_set, NULL); + raise_exception(EXCP_PAGE); + + /* never comes here */ + return 1; } #elif defined(TARGET_SPARC) static inline int handle_cpu_signal(unsigned long pc, unsigned long address, Index: linux-user/main.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v retrieving revision 1.58 diff -u -r1.58 main.c --- linux-user/main.c 12 Jan 2005 22:34:47 -0000 1.58 +++ linux-user/main.c 3 Feb 2005 14:04:53 -0000 @@ -365,6 +365,16 @@ } } break; + case EXCP_PAGE: + { + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* XXX: check env->error_code */ + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->address; + queue_signal(info.si_signo, &info); + } + break; case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ break; Index: target-arm/cpu.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/cpu.h,v retrieving revision 1.5 diff -u -r1.5 cpu.h --- target-arm/cpu.h 31 Jan 2005 20:43:28 -0000 1.5 +++ target-arm/cpu.h 3 Feb 2005 14:04:53 -0000 @@ -26,6 +26,7 @@ #define EXCP_UDEF 1 /* undefined instruction */ #define EXCP_SWI 2 /* software interrupt */ +#define EXCP_PAGE 3 typedef struct CPUARMState { uint32_t regs[16]; @@ -45,6 +46,7 @@ int interrupt_request; struct TranslationBlock *current_tb; int user_mode_only; + uint32_t address; /* in order to avoid passing too many arguments to the memory write helpers, we store some rarely used information in the CPU Index: target-arm/exec.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/exec.h,v retrieving revision 1.3 diff -u -r1.3 exec.h --- target-arm/exec.h 31 Jan 2005 20:43:28 -0000 1.3 +++ target-arm/exec.h 3 Feb 2005 14:04:53 -0000 @@ -31,6 +31,8 @@ void cpu_unlock(void); void cpu_loop_exit(void); +void raise_exception(int tt); + /* Implemented CPSR bits. */ #define CACHED_CPSR_BITS 0xf8000000 static inline int compute_cpsr(void) Index: target-arm/op.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/op.c,v retrieving revision 1.7 diff -u -r1.7 op.c --- target-arm/op.c 2 Feb 2005 20:43:01 -0000 1.7 +++ target-arm/op.c 3 Feb 2005 14:04:53 -0000 @@ -840,6 +840,12 @@ /* exceptions */ +void raise_exception(int tt) +{ + env->exception_index = tt; + cpu_loop_exit(); +} + void OPPROTO op_swi(void) { env->exception_index = EXCP_SWI; --Boundary-00=_7BjACkxbwagc5fc--