From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:37604) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UCaRG-0002sr-G0 for qemu-devel@nongnu.org; Mon, 04 Mar 2013 13:48:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UCaRA-0007tL-SA for qemu-devel@nongnu.org; Mon, 04 Mar 2013 13:48:42 -0500 Received: from hall.aurel32.net ([2001:470:1f15:c4f::1]:37110) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UCaRA-0007t6-Hd for qemu-devel@nongnu.org; Mon, 04 Mar 2013 13:48:36 -0500 Date: Mon, 4 Mar 2013 19:48:32 +0100 From: Aurelien Jarno Message-ID: <20130304184832.GC23040@ohm.aurel32.net> References: <1357858222-12268-1-git-send-email-meadori@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline In-Reply-To: <1357858222-12268-1-git-send-email-meadori@codesourcery.com> Subject: Re: [Qemu-devel] [PATCH v2] MIPS: Translate breaks and traps into the appropriate signal List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Meador Inge Cc: qemu-devel@nongnu.org On Thu, Jan 10, 2013 at 04:50:22PM -0600, Meador Inge wrote: > GCC and GAS are capable of generating traps or breaks to check for > division by zero. Additionally, GAS is capable of generating traps > or breaks to check for overflow on certain division and multiplication > operations. The Linux kernel translates these traps and breaks into > signals. This patch implements the corresponding feature in QEMU. > > Signed-off-by: Meador Inge > --- > Changes since v1: > > * Moved the BRK_* enumerations from target-mips/cpu.h to > linux-user/main.c since they are only used in main.c > > * Fixed some style violations found by checkpatch.pl. > > * Removed a superfluous break. > > linux-user/main.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 75 insertions(+), 1 deletion(-) > > diff --git a/linux-user/main.c b/linux-user/main.c > index 9ade1bf..583940c 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -2182,6 +2182,33 @@ static int do_store_exclusive(CPUMIPSState *env) > return segv; > } > > +/* Break codes */ > +enum { > + BRK_OVERFLOW = 6, > + BRK_DIVZERO = 7 > +}; > + > +static int do_break(CPUMIPSState *env, target_siginfo_t *info, > + unsigned int code) > +{ > + int ret = -1; > + > + switch (code) { > + case BRK_OVERFLOW: > + case BRK_DIVZERO: > + info->si_signo = TARGET_SIGFPE; > + info->si_errno = 0; > + info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV; > + queue_signal(env, info->si_signo, &*info); > + ret = 0; > + break; > + default: > + break; > + } > + > + return ret; > +} > + > void cpu_loop(CPUMIPSState *env) > { > target_siginfo_t info; > @@ -2297,8 +2324,55 @@ done_syscall: > info.si_code = TARGET_ILL_ILLOPC; > queue_signal(env, info.si_signo, &info); > break; > + /* The code below was inspired by the MIPS Linux kernel trap > + * handling code in arch/mips/kernel/traps.c. > + */ > + case EXCP_BREAK: > + { > + abi_ulong trap_instr; > + unsigned int code; > + > + ret = get_user_ual(trap_instr, env->active_tc.PC); > + if (ret != 0) { > + goto error; > + } > + > + /* As described in the original Linux kernel code, the > + * below checks on 'code' are to work around an old > + * assembly bug. > + */ > + code = ((trap_instr >> 6) & ((1 << 20) - 1)); > + if (code >= (1 << 10)) { > + code >>= 10; > + } > + > + if (do_break(env, &info, code) != 0) { > + goto error; > + } > + } > + break; > + case EXCP_TRAP: > + { > + abi_ulong trap_instr; > + unsigned int code = 0; > + > + ret = get_user_ual(trap_instr, env->active_tc.PC); > + if (ret != 0) { > + goto error; > + } > + > + /* The immediate versions don't provide a code. */ > + if (!(trap_instr & 0xFC000000)) { > + code = ((trap_instr >> 6) & ((1 << 10) - 1)); > + } > + > + if (do_break(env, &info, code) != 0) { > + goto error; > + } > + } > + break; > default: > - // error: > +error: > fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", > trapnr); > cpu_dump_state(env, stderr, fprintf, 0); Thanks, applied, and sorry for the delay. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurelien@aurel32.net http://www.aurel32.net