aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorNadav Amit <namit@cs.technion.ac.il>2014-12-24 19:52:18 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2015-01-08 16:48:05 -0500
commit16bebefe29d8495c89961a9d57ea1947547a5211 (patch)
tree9d5c2504dbacf160c8c0e01bdaa8a522e21b1975 /arch
parent3313bc4ee83c4e2870d8e83800c6064b0d215679 (diff)
KVM: x86: fnstcw and fnstsw may cause spurious exception
Since the operand size of fnstcw and fnstsw is updated during the execution, the emulation may cause spurious exceptions as it reads the memory beforehand. Marking these instructions as Mov (since the previous value is ignored) and DstMem16 to simplify the setting of operand size. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index abe95d2e6848..fff11885a3a0 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -86,6 +86,7 @@
86#define DstAcc (OpAcc << DstShift) 86#define DstAcc (OpAcc << DstShift)
87#define DstDI (OpDI << DstShift) 87#define DstDI (OpDI << DstShift)
88#define DstMem64 (OpMem64 << DstShift) 88#define DstMem64 (OpMem64 << DstShift)
89#define DstMem16 (OpMem16 << DstShift)
89#define DstImmUByte (OpImmUByte << DstShift) 90#define DstImmUByte (OpImmUByte << DstShift)
90#define DstDX (OpDX << DstShift) 91#define DstDX (OpDX << DstShift)
91#define DstAccLo (OpAccLo << DstShift) 92#define DstAccLo (OpAccLo << DstShift)
@@ -1057,8 +1058,6 @@ static int em_fnstcw(struct x86_emulate_ctxt *ctxt)
1057 asm volatile("fnstcw %0": "+m"(fcw)); 1058 asm volatile("fnstcw %0": "+m"(fcw));
1058 ctxt->ops->put_fpu(ctxt); 1059 ctxt->ops->put_fpu(ctxt);
1059 1060
1060 /* force 2 byte destination */
1061 ctxt->dst.bytes = 2;
1062 ctxt->dst.val = fcw; 1061 ctxt->dst.val = fcw;
1063 1062
1064 return X86EMUL_CONTINUE; 1063 return X86EMUL_CONTINUE;
@@ -1075,8 +1074,6 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt)
1075 asm volatile("fnstsw %0": "+m"(fsw)); 1074 asm volatile("fnstsw %0": "+m"(fsw));
1076 ctxt->ops->put_fpu(ctxt); 1075 ctxt->ops->put_fpu(ctxt);
1077 1076
1078 /* force 2 byte destination */
1079 ctxt->dst.bytes = 2;
1080 ctxt->dst.val = fsw; 1077 ctxt->dst.val = fsw;
1081 1078
1082 return X86EMUL_CONTINUE; 1079 return X86EMUL_CONTINUE;
@@ -3863,7 +3860,7 @@ static const struct gprefix pfx_0f_e7 = {
3863}; 3860};
3864 3861
3865static const struct escape escape_d9 = { { 3862static const struct escape escape_d9 = { {
3866 N, N, N, N, N, N, N, I(DstMem, em_fnstcw), 3863 N, N, N, N, N, N, N, I(DstMem16 | Mov, em_fnstcw),
3867}, { 3864}, {
3868 /* 0xC0 - 0xC7 */ 3865 /* 0xC0 - 0xC7 */
3869 N, N, N, N, N, N, N, N, 3866 N, N, N, N, N, N, N, N,
@@ -3905,7 +3902,7 @@ static const struct escape escape_db = { {
3905} }; 3902} };
3906 3903
3907static const struct escape escape_dd = { { 3904static const struct escape escape_dd = { {
3908 N, N, N, N, N, N, N, I(DstMem, em_fnstsw), 3905 N, N, N, N, N, N, N, I(DstMem16 | Mov, em_fnstsw),
3909}, { 3906}, {
3910 /* 0xC0 - 0xC7 */ 3907 /* 0xC0 - 0xC7 */
3911 N, N, N, N, N, N, N, N, 3908 N, N, N, N, N, N, N, N,