diff mbox

[RFC,2/3] target-i386: Raise #UD on accessing non-existent control registers

Message ID 1362017554-1260-2-git-send-email-hpa@zytor.com
State New
Headers show

Commit Message

H. Peter Anvin Feb. 28, 2013, 2:12 a.m. UTC
From: "H. Peter Anvin" <hpa@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 <hpa@zytor.com>
---
 target-i386/misc_helper.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

Comments

Aurelien Jarno March 28, 2013, 7:15 p.m. UTC | #1
On Wed, Feb 27, 2013 at 06:12:33PM -0800, H. Peter Anvin wrote:
> From: "H. Peter Anvin" <hpa@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 <hpa@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 <aurelien@aurel32.net>
diff mbox

Patch

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;
     }
 }