aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-12-06 09:15:02 -0500
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:53:19 -0500
commite934c9c1c8742872a53efb84966d9c1d7b8c8e24 (patch)
tree37292af0e1f065b74e9eaf016653df798bb136b0
parent7ee5d940f5064a7a4f0e53a8ffe755bc26a8b0f1 (diff)
KVM: x86 emulator: fix eflags preparation for emulation
We prepare eflags for the emulated instruction, then clobber it with an 'andl'. Fix by popping eflags as the last thing in the sequence. Patch taken from Xen (16143:959b4b92b6bf) Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--drivers/kvm/x86_emulate.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 2e259a847697..f423b0e327f4 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -256,21 +256,21 @@ static u16 twobyte_table[256] = {
256#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF) 256#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)
257 257
258/* Before executing instruction: restore necessary bits in EFLAGS. */ 258/* Before executing instruction: restore necessary bits in EFLAGS. */
259#define _PRE_EFLAGS(_sav, _msk, _tmp) \ 259#define _PRE_EFLAGS(_sav, _msk, _tmp) \
260 /* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); */ \ 260 /* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
261 "push %"_sav"; " \ 261 "movl %"_sav",%"_LO32 _tmp"; " \
262 "movl %"_msk",%"_LO32 _tmp"; " \ 262 "push %"_tmp"; " \
263 "andl %"_LO32 _tmp",("_STK"); " \ 263 "push %"_tmp"; " \
264 "pushf; " \ 264 "movl %"_msk",%"_LO32 _tmp"; " \
265 "notl %"_LO32 _tmp"; " \ 265 "andl %"_LO32 _tmp",("_STK"); " \
266 "andl %"_LO32 _tmp",("_STK"); " \ 266 "pushf; " \
267 "pop %"_tmp"; " \ 267 "notl %"_LO32 _tmp"; " \
268 "orl %"_LO32 _tmp",("_STK"); " \ 268 "andl %"_LO32 _tmp",("_STK"); " \
269 "popf; " \ 269 "andl %"_LO32 _tmp","__stringify(BITS_PER_LONG/4)"("_STK"); " \
270 /* _sav &= ~msk; */ \ 270 "pop %"_tmp"; " \
271 "movl %"_msk",%"_LO32 _tmp"; " \ 271 "orl %"_LO32 _tmp",("_STK"); " \
272 "notl %"_LO32 _tmp"; " \ 272 "popf; " \
273 "andl %"_LO32 _tmp",%"_sav"; " 273 "pop %"_sav"; "
274 274
275/* After executing instruction: write-back necessary bits in EFLAGS. */ 275/* After executing instruction: write-back necessary bits in EFLAGS. */
276#define _POST_EFLAGS(_sav, _msk, _tmp) \ 276#define _POST_EFLAGS(_sav, _msk, _tmp) \