Commit 16bebefe authored by Nadav Amit's avatar Nadav Amit Committed by Paolo Bonzini

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: default avatarNadav Amit <namit@cs.technion.ac.il>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 3313bc4e
...@@ -86,6 +86,7 @@ ...@@ -86,6 +86,7 @@
#define DstAcc (OpAcc << DstShift) #define DstAcc (OpAcc << DstShift)
#define DstDI (OpDI << DstShift) #define DstDI (OpDI << DstShift)
#define DstMem64 (OpMem64 << DstShift) #define DstMem64 (OpMem64 << DstShift)
#define DstMem16 (OpMem16 << DstShift)
#define DstImmUByte (OpImmUByte << DstShift) #define DstImmUByte (OpImmUByte << DstShift)
#define DstDX (OpDX << DstShift) #define DstDX (OpDX << DstShift)
#define DstAccLo (OpAccLo << DstShift) #define DstAccLo (OpAccLo << DstShift)
...@@ -1057,8 +1058,6 @@ static int em_fnstcw(struct x86_emulate_ctxt *ctxt) ...@@ -1057,8 +1058,6 @@ static int em_fnstcw(struct x86_emulate_ctxt *ctxt)
asm volatile("fnstcw %0": "+m"(fcw)); asm volatile("fnstcw %0": "+m"(fcw));
ctxt->ops->put_fpu(ctxt); ctxt->ops->put_fpu(ctxt);
/* force 2 byte destination */
ctxt->dst.bytes = 2;
ctxt->dst.val = fcw; ctxt->dst.val = fcw;
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
...@@ -1075,8 +1074,6 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt) ...@@ -1075,8 +1074,6 @@ static int em_fnstsw(struct x86_emulate_ctxt *ctxt)
asm volatile("fnstsw %0": "+m"(fsw)); asm volatile("fnstsw %0": "+m"(fsw));
ctxt->ops->put_fpu(ctxt); ctxt->ops->put_fpu(ctxt);
/* force 2 byte destination */
ctxt->dst.bytes = 2;
ctxt->dst.val = fsw; ctxt->dst.val = fsw;
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
...@@ -3863,7 +3860,7 @@ static const struct gprefix pfx_0f_e7 = { ...@@ -3863,7 +3860,7 @@ static const struct gprefix pfx_0f_e7 = {
}; };
static const struct escape escape_d9 = { { static const struct escape escape_d9 = { {
N, N, N, N, N, N, N, I(DstMem, em_fnstcw), N, N, N, N, N, N, N, I(DstMem16 | Mov, em_fnstcw),
}, { }, {
/* 0xC0 - 0xC7 */ /* 0xC0 - 0xC7 */
N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
...@@ -3905,7 +3902,7 @@ static const struct escape escape_db = { { ...@@ -3905,7 +3902,7 @@ static const struct escape escape_db = { {
} }; } };
static const struct escape escape_dd = { { static const struct escape escape_dd = { {
N, N, N, N, N, N, N, I(DstMem, em_fnstsw), N, N, N, N, N, N, N, I(DstMem16 | Mov, em_fnstsw),
}, { }, {
/* 0xC0 - 0xC7 */ /* 0xC0 - 0xC7 */
N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment