qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] x86: Fix exceptions for fxsave/fxrstor


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH] x86: Fix exceptions for fxsave/fxrstor
Date: Sun, 4 Oct 2009 12:05:16 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

On Fri, Oct 02, 2009 at 10:28:57PM +0200, Kevin Wolf wrote:
> 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

Agreed.

> * Generate #UD if the LOCK prefix is used

Agreed.

> * For CR0.EM = 1 #NM is generated, not #UD

This does not match the Intel manual:

| #NM If CR0.TS[bit 3] = 1.

| #UD If CR0.EM[bit 2] = 1.
|     If CPUID.01H:EDX.FXSR[bit 24] = 0.
|     If the LOCK prefix is used.

 
> Signed-off-by: Kevin Wolf <address@hidden>
> ---
>  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
> 
> 
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
address@hidden                 http://www.aurel32.net




reply via email to

[Prev in Thread] Current Thread [Next in Thread]