]> xenbits.xensource.com Git - xen.git/commitdiff
x86/emulator: workaround for AMD erratum 573
authorJan Beulich <jbeulich@suse.com>
Wed, 7 Mar 2012 08:17:44 +0000 (08:17 +0000)
committerJan Beulich <jbeulich@suse.com>
Wed, 7 Mar 2012 08:17:44 +0000 (08:17 +0000)
The only cases where we might end up emulating fsincos (as any other
x87 operations without memory operands) are
- when a HVM guest is in real mode (not applicable on AMD)
- between two half page table updates in PAE mode (unlikely, and not
  doing the emulation here does affect only performance, not
  correctness)
- when a guest maliciously (or erroneously) modifies an (MMIO or page
  table update) instruction under emulation (unspecified behavior)

Hence, in order to avoid the erratum to cause harm to the entire host,
don't emulate fsincos on the affected AMD CPU families.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
xen-unstable changeset:   24417:1452fb248cd5
xen-unstable date:        Fri Dec 16 15:45:40 2011 +0100

tools/tests/x86_emulator/x86_emulate.c
xen/arch/x86/x86_emulate.c
xen/arch/x86/x86_emulate/x86_emulate.c
xen/include/asm-x86/amd.h

index a58a7b81789699a59d6e44908674ee591c5afa4c..95e9ff603d7f0574f8fd58e88fdcd66f6c3a67c7 100644 (file)
@@ -3,5 +3,7 @@
 #include <string.h>
 #include <public/xen.h>
 
+#define cpu_has_amd_erratum(nr) 0
+
 #include "x86_emulate/x86_emulate.h"
 #include "x86_emulate/x86_emulate.c"
index fbf740efeea16160e868adef9ba9663c8cb3b4e1..91f524fc873501c028564bb5579f84ca74a0d64a 100644 (file)
  */
 
 #include <asm/x86_emulate.h>
+#include <asm/processor.h> /* current_cpu_info */
+#include <asm/amd.h> /* cpu_has_amd_erratum() */
 
 /* Avoid namespace pollution. */
 #undef cmpxchg
+#undef cpuid
+
+#define cpu_has_amd_erratum(nr) \
+        cpu_has_amd_erratum(&current_cpu_data, AMD_ERRATUM_##nr)
 
 #include "x86_emulate/x86_emulate.c"
index aa491f1de455b58c15164a9bd31da96491c747d2..c070656a30428b9ea2f7607fc69bffbec54e1a32 100644 (file)
@@ -2578,6 +2578,9 @@ x86_emulate(
     case 0xd9: /* FPU 0xd9 */
         switch ( modrm )
         {
+        case 0xfb: /* fsincos */
+            fail_if(cpu_has_amd_erratum(573));
+            /* fall through */
         case 0xc0 ... 0xc7: /* fld %stN */
         case 0xc8 ... 0xcf: /* fxch %stN */
         case 0xd0: /* fnop */
@@ -2603,7 +2606,6 @@ x86_emulate(
         case 0xf8: /* fprem */
         case 0xf9: /* fyl2xp1 */
         case 0xfa: /* fsqrt */
-        case 0xfb: /* fsincos */
         case 0xfc: /* frndint */
         case 0xfd: /* fscale */
         case 0xfe: /* fsin */
index 283c17207468b80c0e876bf1313f56f9baec5210..708fed2fd26da5edd8ab0f3fee2b6f3e2cc09bee 100644 (file)
     AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf),     \
                         AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf))
 
+#define AMD_ERRATUM_573                                                        \
+    AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x0f, 0x0, 0x0, 0xff, 0xf),     \
+                       AMD_MODEL_RANGE(0x10, 0x0, 0x0, 0xff, 0xf),     \
+                       AMD_MODEL_RANGE(0x11, 0x0, 0x0, 0xff, 0xf),     \
+                       AMD_MODEL_RANGE(0x12, 0x0, 0x0, 0xff, 0xf))
+
 struct cpuinfo_x86;
 int cpu_has_amd_erratum(const struct cpuinfo_x86 *, int, ...);