From patchwork Fri Jul 27 18:55:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Ogilvie X-Patchwork-Id: 173785 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1ED252C0040 for ; Sat, 28 Jul 2012 06:31:31 +1000 (EST) Received: from localhost ([::1]:39146 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sur46-0004M0-Ky for incoming@patchwork.ozlabs.org; Fri, 27 Jul 2012 16:23:14 -0400 Received: from eggs.gnu.org ([208.118.235.92]:39886) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Supjl-0006NC-3b for qemu-devel@nongnu.org; Fri, 27 Jul 2012 14:58:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Supjj-0001J4-UC for qemu-devel@nongnu.org; Fri, 27 Jul 2012 14:58:09 -0400 Received: from qmta13.emeryville.ca.mail.comcast.net ([76.96.27.243]:43923) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Supjj-0001Ir-Kg for qemu-devel@nongnu.org; Fri, 27 Jul 2012 14:58:07 -0400 Received: from omta22.emeryville.ca.mail.comcast.net ([76.96.30.89]) by qmta13.emeryville.ca.mail.comcast.net with comcast id fWqp1j0061vN32cADWy5NK; Fri, 27 Jul 2012 18:58:05 +0000 Received: from mmogilvi.homeip.net ([24.9.53.136]) by omta22.emeryville.ca.mail.comcast.net with comcast id fWy41j00B2wKXRC8iWy4jQ; Fri, 27 Jul 2012 18:58:05 +0000 Received: by mmogilvi.homeip.net (Postfix, from userid 501) id BF9CB1E96019; Fri, 27 Jul 2012 12:58:03 -0600 (MDT) From: Matthew Ogilvie To: qemu-devel@nongnu.org Date: Fri, 27 Jul 2012 12:55:56 -0600 Message-Id: <1343415357-5637-3-git-send-email-mmogilvi_qemu@miniinfo.net> X-Mailer: git-send-email 1.7.10.2.484.gcd07cc5 In-Reply-To: <1343415357-5637-1-git-send-email-mmogilvi_qemu@miniinfo.net> References: <1343415357-5637-1-git-send-email-mmogilvi_qemu@miniinfo.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 76.96.27.243 X-Mailman-Approved-At: Fri, 27 Jul 2012 16:22:31 -0400 Cc: Matthew Ogilvie Subject: [Qemu-devel] [PATCH 2/3] target-i386/translate.c: mov to/from crN/drN: ignore mod bits 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 Microport UNIX System V/386 v 2.1 (ca 1987) uses mod R/M bytes for the control register mov instructions where the mod bits are 0, even though the 80386 spec claims they are "always" 1's. The fact that it ran at all clearly indicates the real chips (at least 386 and 486) just ignores the bits and assumes they are 1's, rather than trigger an illegal instruction if they aren't. Also fixed: The dissassembled kernel also accesses debug registers in a similar way, although other problems prevent me verifiing that those instructions are reachable in UNIX. Signed-off-by: Matthew Ogilvie --- Alternatives?: Potentially someone might want to make this dependent on some kind of configuration option (what specific CPU it is emulating, or some kind of quirks flag). Or somehow log if it encounters unspecified instructions like this, as a kind of warning mechanism for someone debugging an OS. (Although I'm not sure exactly what the qemu way to log such a thing would be.) But my initial thought is that neither of these are worth the effort. ------ Matthew Ogilvie [mmogilvi_qemu@miniinfo.net] ------ target-i386/translate.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 1988dae..d056842 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7465,8 +7465,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { modrm = ldub_code(s->pc++); - if ((modrm & 0xc0) != 0xc0) - goto illegal_op; + /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). + * The 80386 reference manual says the bits are + * always 1, and doesn't say what happens if they aren't. + * But testing shows that the bits are just assumed to be + * 1s. + */ rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s)) @@ -7507,8 +7511,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { modrm = ldub_code(s->pc++); - if ((modrm & 0xc0) != 0xc0) - goto illegal_op; + /* Ignore the mod bits (assume (modrm&0xc0)==0xc0). + * The 80386 reference manual says the bits are + * always 1, and doesn't say what happens if they aren't. + * But testing shows that the bits are just assumed to be + * 1s. + */ rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; if (CODE64(s))