From patchwork Tue Jul 14 16:38:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Alrae X-Patchwork-Id: 495174 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D8D851402AC for ; Wed, 15 Jul 2015 02:39:08 +1000 (AEST) Received: from localhost ([::1]:60492 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZF3EY-0008SF-TA for incoming@patchwork.ozlabs.org; Tue, 14 Jul 2015 12:39:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53243) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZF3EH-0008Ay-8B for qemu-devel@nongnu.org; Tue, 14 Jul 2015 12:38:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZF3ED-0004NU-Kn for qemu-devel@nongnu.org; Tue, 14 Jul 2015 12:38:49 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:1877) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZF3ED-0004N8-Fx for qemu-devel@nongnu.org; Tue, 14 Jul 2015 12:38:45 -0400 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id CE387F9AD2476; Tue, 14 Jul 2015 17:38:40 +0100 (IST) Received: from lalrae-linux.kl.imgtec.org (192.168.14.163) by KLMAIL01.kl.imgtec.org (192.168.5.35) with Microsoft SMTP Server (TLS) id 14.3.195.1; Tue, 14 Jul 2015 17:38:43 +0100 From: Leon Alrae To: Date: Tue, 14 Jul 2015 17:38:32 +0100 Message-ID: <1436891912-14742-1-git-send-email-leon.alrae@imgtec.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 X-Originating-IP: [192.168.14.163] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.59.15.196 Cc: aurelien@aurel32.net, rth@twiddle.net Subject: [Qemu-devel] [PATCH] target-mips: apply workaround for TCG optimizations for MFC1 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org There seems to be an issue when trying to keep a pointer in bottom 32-bits of a 64-bit floating point register. Load and store instructions accessing this address for some reason use the whole 64-bit content of floating point register rather than truncated 32-bit value. The following load uses incorrect address which leads to a crash if upper 32 bits of $f0 isn't 0: 0x00400c60: mfc1 t8,$f0 0x00400c64: lw t9,0(t8) It can be reproduced with the following linux userland program when running on a MIPS32 with CP0.Status.FR=1 (by default mips32r5-generic and mips32r6-generic CPUs have this bit set in linux-user). int main(int argc, char *argv[]) { int tmp = 0x11111111; /* Set f0 */ __asm__ ("mtc1 %0, $f0\n" "mthc1 %1, $f0\n" : : "r" (&tmp), "r" (tmp)); /* At this point $f0: w:76fff040 d:1111111176fff040 */ __asm__ ("mfc1 $t8, $f0\n" "lw $t9, 0($t8)\n"); /* <--- crash! */ return 0; } Running above program in normal (non-singlestep mode) leads to: Program received signal SIGSEGV, Segmentation fault. 0x00005555559f6f37 in static_code_gen_buffer () (gdb) x/i 0x00005555559f6f37 => 0x5555559f6f37 : mov %gs:0x0(%rbp),%ebp (gdb) info registers rbp rbp 0x1111111176fff040 0x1111111176fff040 The program runs fine in singlestep mode, or with disabled TCG optimizations. Also, I'm not able to reproduce it in system emulation. Signed-off-by: Leon Alrae --- I had been investigating this some time ago, but had to move to other things and haven't managed to get back to it. And now, since 2.4 release is relatively close I think workaround is better than nothing (apparently some MIPS32R6 compilers may keep a pointer in a floating point register which exposes this problem in QEMU). Ideas and comments are welcome. More dumps if anyone is interested (I isolated TB for these two instructions by stopping translation after mthc1 and lw): IN: main 0x00400c60: mfc1 t8,$f0 0x00400c64: lw t9,0(t8) OP: ld_i32 tmp0,env,$0xfffffffffffffffc movi_i32 tmp1,$0x0 brcond_i32 tmp0,tmp1,ne,$L0 ---- 0x400c60 mov_i32 tmp1,w0.d0 mov_i32 tmp0,tmp1 mov_i32 t8,tmp0 ---- 0x400c64 mov_i32 tmp0,t8 qemu_ld_i32 tmp0,tmp0,un+leul,2 mov_i32 t9,tmp0 goto_tb $0x0 movi_i32 PC,$0x400c68 exit_tb $0x7ffff35d5d30 set_label $L0 exit_tb $0x7ffff35d5d33 OP after optimization and liveness analysis: ld_i32 tmp0,env,$0xfffffffffffffffc movi_i32 tmp1,$0x0 brcond_i32 tmp0,tmp1,ne,$L0 ---- 0x400c60 mov_i32 tmp1,w0.d0 mov_i32 tmp0,tmp1 mov_i32 t8,tmp0 ---- 0x400c64 qemu_ld_i32 tmp0,t8,un+leul,2 mov_i32 t9,tmp0 goto_tb $0x0 movi_i32 PC,$0x400c68 exit_tb $0x7ffff35d5d30 set_label $L0 exit_tb $0x7ffff35d5d33 OUT: [size=78] 0x5555559f6f20: mov -0x4(%r14),%ebp 0x5555559f6f24: test %ebp,%ebp 0x5555559f6f26: jne 0x5555559f6f5f 0x5555559f6f2c: mov 0xe8(%r14),%rbp 0x5555559f6f33: mov %ebp,0x60(%r14) 0x5555559f6f37: mov %gs:0x0(%rbp),%ebp 0x5555559f6f3b: mov %ebp,0x64(%r14) 0x5555559f6f3f: jmpq 0x5555559f6f44 0x5555559f6f44: mov $0x400c68,%ebp 0x5555559f6f49: mov %ebp,0x80(%r14) 0x5555559f6f50: mov $0x7ffff35d5d30,%rax 0x5555559f6f5a: jmpq 0x5555579e3936 0x5555559f6f5f: mov $0x7ffff35d5d33,%rax 0x5555559f6f69: jmpq 0x5555579e3936 --- target-mips/translate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/target-mips/translate.c b/target-mips/translate.c index 3ae09f8..3f6b701 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -8731,6 +8731,12 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) } gen_store_gpr(t0, rt); opn = "mfc1"; +#if defined(CONFIG_USER_ONLY) + /* FIXME + Workaround: end translation to avoid TCG optimization with next + instruction. */ + ctx->bstate = BS_STOP; +#endif break; case OPC_MTC1: gen_load_gpr(t0, rt);