On Wed, Feb 27, 2013 at 06:12:33PM -0800, H. Peter Anvin wrote:
> From: "H. Peter Anvin" <h...@zytor.com>
> 
> If we touch control registers that don't exist, either read or write,
> raise the #UD exception (undefined opcode).
> 
> This is useful for testing booting on old CPUs.
> 
> CR4 is assumed to exist if and only if there are CPU features other
> than the FPU defined (typically at least VME).
> 
> Signed-off-by: H. Peter Anvin <h...@zytor.com>
> ---
>  target-i386/misc_helper.c | 25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
> index 1ff25d1..6da3f32 100644
> --- a/target-i386/misc_helper.c
> +++ b/target-i386/misc_helper.c
> @@ -154,9 +154,18 @@ target_ulong helper_read_crN(CPUX86State *env, int reg)
>  
>      cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0);
>      switch (reg) {
> -    default:
> +    case 0:
> +    case 2:
> +    case 3:
>          val = env->cr[reg];
>          break;
> +    case 4:
> +        if (env->cpuid_features <= CPUID_FP87) {
> +            raise_exception_err(env, EXCP06_ILLOP, 0);
> +        } else {
> +            val = env->cr[reg];
> +        }
> +        break;
>      case 8:
>          if (!(env->hflags2 & HF2_VINTR_MASK)) {
>              val = cpu_get_apic_tpr(env->apic_state);
> @@ -164,6 +173,9 @@ target_ulong helper_read_crN(CPUX86State *env, int reg)
>              val = env->v_tpr;
>          }
>          break;
> +    default:
> +        raise_exception_err(env, EXCP06_ILLOP, 0);
> +        break;
>      }
>      return val;
>  }
> @@ -175,11 +187,18 @@ void helper_write_crN(CPUX86State *env, int reg, 
> target_ulong t0)
>      case 0:
>          cpu_x86_update_cr0(env, t0);
>          break;
> +    case 2:
> +        env->cr[reg] = t0;
> +        break;
>      case 3:
>          cpu_x86_update_cr3(env, t0);
>          break;
>      case 4:
> -        cpu_x86_update_cr4(env, t0);
> +        if (env->cpuid_features <= CPUID_FP87) {
> +            raise_exception_err(env, EXCP06_ILLOP, 0);
> +        } else {
> +            cpu_x86_update_cr4(env, t0);
> +        }
>          break;
>      case 8:
>          if (!(env->hflags2 & HF2_VINTR_MASK)) {
> @@ -188,7 +207,7 @@ void helper_write_crN(CPUX86State *env, int reg, 
> target_ulong t0)
>          env->v_tpr = t0 & 0x0f;
>          break;
>      default:
> -        env->cr[reg] = t0;
> +        raise_exception_err(env, EXCP06_ILLOP, 0);
>          break;
>      }
>  }

Reviewed-by: Aurelien Jarno <aurel...@aurel32.net>


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

Reply via email to