From patchwork Wed Nov 19 17:29:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 412464 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 935E0140281 for ; Thu, 20 Nov 2014 04:29:42 +1100 (AEDT) Received: from localhost ([::1]:59866 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xr94W-0006aw-BX for incoming@patchwork.ozlabs.org; Wed, 19 Nov 2014 12:29:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58089) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xr948-0006JZ-B5 for qemu-devel@nongnu.org; Wed, 19 Nov 2014 12:29:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Xr940-0007F4-Jm for qemu-devel@nongnu.org; Wed, 19 Nov 2014 12:29:16 -0500 Received: from relay1.mentorg.com ([192.94.38.131]:33299) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xr940-0007EY-CQ for qemu-devel@nongnu.org; Wed, 19 Nov 2014 12:29:08 -0500 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-FEM-01.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1Xr93y-0005vf-5N from Maciej_Rozycki@mentor.com ; Wed, 19 Nov 2014 09:29:06 -0800 Received: from localhost (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server (TLS) id 14.3.181.6; Wed, 19 Nov 2014 17:29:04 +0000 Date: Wed, 19 Nov 2014 17:29:00 +0000 From: "Maciej W. Rozycki" To: Message-ID: User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 192.94.38.131 Cc: Leon Alrae , Aurelien Jarno Subject: [Qemu-devel] [PATCH] target-mips: Correct 32-bit address space wrapping 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 Make sure the address space is unconditionally wrapped on 32-bit processors, that is ones that do not implement at least the MIPS III ISA. Also make MIPS16 SAVE and RESTORE instructions use address calculation rather than plain arithmetic operations for stack pointer manipulation so that their semantics for stack accesses follows the architecture specification. That in particular applies to user software run on 64-bit processors with the CP0.Status.UX bit clear where the address space is wrapped to 32 bits. Signed-off-by: Maciej W. Rozycki Reviewed-by: Leon Alrae --- Hi, This change was also tested by running full GCC, G++ and glibc mips-linux-gnu toolchain test suites under Linux (Debian Wheezy) run in QEMU in the system emulation mode, for the following multilibs: -EB -EB -mips16 -EB -mmicromips -EB -mabi=n32 -EB -mabi=64 and the -EL variants of same. Of these standard MIPS o32 testing was run on a 24Kf processor and n64/n32 testing was run on a 5KEf processor, using a 32-bit and a 64-bit kernel respectively. MIPS16 o32 testing was run on an artificial 5KEf-mips16 processor -- like a real 5KEf one, but with the MIPS16 ASE enabled, and a 64-bit kernel. Finally microMIPS o32 testing was run on an artificial 24Kf-micromips processor -- like a real 24Kf one, but with the microMIPS ASE enabled, and a 32-bit kernel built as microMIPS code itself. The original test result counts were as follows: Result Count ERROR 20 FAIL 300 PASS 1732076 XPASS 335 XFAIL 6527 UNRESOLVED 26 UNSUPPORTED 50854 Total 1790138 After the change they were: Result Count ERROR 20 FAIL 298 PASS 1732078 XPASS 336 XFAIL 6526 UNRESOLVED 26 UNSUPPORTED 50854 Total 1790138 The changes in results were as follows: PASS -> FAIL: qemu-n32-el/glibc.sum: nptl/tst-cancel17 FAIL -> PASS: qemu-micromips/glibc.sum: nptl/tst-cancel17 FAIL -> PASS: qemu-micromips/glibc.sum: nptl/tst-setuid3 FAIL -> PASS: qemu-mips16-el/glibc.sum: nptl/tst-cancelx17 XFAIL -> XPASS: qemu-micromips/glibc.sum: nptl/tst-cancel7 -- as you can see glibc results continue fluctuating although this time they are slightly better than originally. Please apply. Maciej qemu-mips32-addr.diff Index: qemu-git-trunk/target-mips/cpu.h =================================================================== --- qemu-git-trunk.orig/target-mips/cpu.h 2014-11-12 07:41:26.597542010 +0000 +++ qemu-git-trunk/target-mips/cpu.h 2014-11-12 07:41:26.597542010 +0000 @@ -843,10 +843,12 @@ static inline void compute_hflags(CPUMIP env->hflags |= MIPS_HFLAG_64; } - if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && - !(env->CP0_Status & (1 << CP0St_UX))) { + if (!(env->insn_flags & ISA_MIPS3)) { env->hflags |= MIPS_HFLAG_AWRAP; - } else if (env->insn_flags & ISA_MIPS32R6) { + } else if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && + !(env->CP0_Status & (1 << CP0St_UX))) { + env->hflags |= MIPS_HFLAG_AWRAP; + } else if (env->insn_flags & ISA_MIPS64R6) { /* Address wrapping for Supervisor and Kernel is specified in R6 */ if ((((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) && !(env->CP0_Status & (1 << CP0St_SX))) || Index: qemu-git-trunk/target-mips/translate.c =================================================================== --- qemu-git-trunk.orig/target-mips/translate.c 2014-11-12 07:41:26.597542010 +0000 +++ qemu-git-trunk/target-mips/translate.c 2014-11-12 07:41:26.597542010 +0000 @@ -10724,6 +10724,7 @@ static void gen_mips16_save (DisasContex { TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); int args, astatic; switch (aregs) { @@ -10782,7 +10783,8 @@ static void gen_mips16_save (DisasContex gen_load_gpr(t0, 29); #define DECR_AND_STORE(reg) do { \ - tcg_gen_subi_tl(t0, t0, 4); \ + tcg_gen_movi_tl(t2, -4); \ + gen_op_addr_add(ctx, t0, t0, t2); \ gen_load_gpr(t1, reg); \ tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \ } while (0) @@ -10866,9 +10868,11 @@ static void gen_mips16_save (DisasContex } #undef DECR_AND_STORE - tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize); + tcg_gen_movi_tl(t2, -framesize); + gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2); tcg_temp_free(t0); tcg_temp_free(t1); + tcg_temp_free(t2); } static void gen_mips16_restore (DisasContext *ctx, @@ -10879,11 +10883,14 @@ static void gen_mips16_restore (DisasCon int astatic; TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); - tcg_gen_addi_tl(t0, cpu_gpr[29], framesize); + tcg_gen_movi_tl(t2, framesize); + gen_op_addr_add(ctx, t0, cpu_gpr[29], t2); #define DECR_AND_LOAD(reg) do { \ - tcg_gen_subi_tl(t0, t0, 4); \ + tcg_gen_movi_tl(t2, -4); \ + gen_op_addr_add(ctx, t0, t0, t2); \ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \ gen_store_gpr(t1, reg); \ } while (0) @@ -10967,9 +10974,11 @@ static void gen_mips16_restore (DisasCon } #undef DECR_AND_LOAD - tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize); + tcg_gen_movi_tl(t2, framesize); + gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2); tcg_temp_free(t0); tcg_temp_free(t1); + tcg_temp_free(t2); } static void gen_addiupc (DisasContext *ctx, int rx, int imm,