aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-03-07 09:05:20 +0000
committerJan Beulich <jbeulich@suse.com>2012-03-07 09:05:20 +0000
commit77f478007da083231c71dd3141a853dcbb98b039 (patch)
treedc70ec7f38535b225590987c3c39dac258c4c1e3
parent95c72af99bd952de17f9bd231f9918d669a5ab93 (diff)
downloadxen-77f478007da083231c71dd3141a853dcbb98b039.tar.gz
xen-77f478007da083231c71dd3141a853dcbb98b039.tar.bz2
xen-77f478007da083231c71dd3141a853dcbb98b039.zip
x86/emulator: workaround for AMD erratum 573
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
-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__ */