aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/tests/x86_emulate.c2
-rw-r--r--xen/arch/x86/x86_emulate.c7
-rw-r--r--xen/arch/x86/x86_emulate/x86_emulate.c4
-rw-r--r--xen/include/asm-x86/amd.h6
4 files changed, 18 insertions, 1 deletions
diff --git a/tools/tests/x86_emulate.c b/tools/tests/x86_emulate.c
index a58a7b8178..95e9ff603d 100644
--- a/tools/tests/x86_emulate.c
+++ b/tools/tests/x86_emulate.c
@@ -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"
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index fbf740efee..d943d26d7d 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -10,8 +10,15 @@
*/
#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
+#undef wbinvd
+
+#define cpu_has_amd_erratum(nr) \
+ cpu_has_amd_erratum(&current_cpu_data, AMD_ERRATUM_##nr)
#include "x86_emulate/x86_emulate.c"
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
index aa491f1de4..c070656a30 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -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 */
diff --git a/xen/include/asm-x86/amd.h b/xen/include/asm-x86/amd.h
index c38984f553..3cdd9df858 100644
--- a/xen/include/asm-x86/amd.h
+++ b/xen/include/asm-x86/amd.h
@@ -134,5 +134,11 @@
AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf), \
AMD_MODEL_RANGE(0x12, 0x0, 0x0, 0x1, 0x0))
+#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))
+
int cpu_has_amd_erratum(const struct cpuinfo_x86 *, int, ...);
#endif /* __AMD_H__ */