From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MtokZ-0001kr-3t for qemu-devel@nongnu.org; Fri, 02 Oct 2009 16:29:11 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MtokU-0001im-Hl for qemu-devel@nongnu.org; Fri, 02 Oct 2009 16:29:10 -0400 Received: from [199.232.76.173] (port=38611 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MtokU-0001ih-8w for qemu-devel@nongnu.org; Fri, 02 Oct 2009 16:29:06 -0400 Received: from mo-p00-ob.rzone.de ([81.169.146.160]:38193) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA1:24) (Exim 4.60) (envelope-from ) id 1MtokT-0002FS-T5 for qemu-devel@nongnu.org; Fri, 02 Oct 2009 16:29:06 -0400 From: Kevin Wolf Date: Fri, 2 Oct 2009 22:28:57 +0200 Message-Id: <1254515337-14321-1-git-send-email-mail@kevin-wolf.de> Subject: [Qemu-devel] [PATCH] x86: Fix exceptions for fxsave/fxrstor List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf This patch corrects the following aspects of exception generation in fxsave/fxrstor: * Generate #GP if the operand is not aligned to a 16 byte boundary * Generate #UD if the LOCK prefix is used * For CR0.EM = 1 #NM is generated, not #UD Signed-off-by: Kevin Wolf --- target-i386/op_helper.c | 10 ++++++++++ target-i386/translate.c | 8 ++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index 33d44b0..3f05532 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -4338,6 +4338,11 @@ void helper_fxsave(target_ulong ptr, int data64) CPU86_LDouble tmp; target_ulong addr; + /* The operand must be 16 byte aligned */ + if (ptr & 0xf) { + raise_exception(EXCP0D_GPF); + } + fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; fptag = 0; for(i = 0; i < 8; i++) { @@ -4394,6 +4399,11 @@ void helper_fxrstor(target_ulong ptr, int data64) CPU86_LDouble tmp; target_ulong addr; + /* The operand must be 16 byte aligned */ + if (ptr & 0xf) { + raise_exception(EXCP0D_GPF); + } + env->fpuc = lduw(ptr); fpus = lduw(ptr + 2); fptag = lduw(ptr + 4); diff --git a/target-i386/translate.c b/target-i386/translate.c index 5b11d7f..9af2eed 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7436,9 +7436,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) switch(op) { case 0: /* fxsave */ if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || - (s->flags & HF_EM_MASK)) + (s->prefix & PREFIX_LOCK)) goto illegal_op; - if (s->flags & HF_TS_MASK) { + if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); break; } @@ -7450,9 +7450,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) break; case 1: /* fxrstor */ if (mod == 3 || !(s->cpuid_features & CPUID_FXSR) || - (s->flags & HF_EM_MASK)) + (s->prefix & PREFIX_LOCK)) goto illegal_op; - if (s->flags & HF_TS_MASK) { + if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) { gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); break; } -- 1.6.0.2