diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 391 |
1 files changed, 109 insertions, 282 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5953dcea752d..2bc1e81045b0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -61,6 +61,8 @@ | |||
61 | #define OpMem8 26ull /* 8-bit zero extended memory operand */ | 61 | #define OpMem8 26ull /* 8-bit zero extended memory operand */ |
62 | #define OpImm64 27ull /* Sign extended 16/32/64-bit immediate */ | 62 | #define OpImm64 27ull /* Sign extended 16/32/64-bit immediate */ |
63 | #define OpXLat 28ull /* memory at BX/EBX/RBX + zero-extended AL */ | 63 | #define OpXLat 28ull /* memory at BX/EBX/RBX + zero-extended AL */ |
64 | #define OpAccLo 29ull /* Low part of extended acc (AX/AX/EAX/RAX) */ | ||
65 | #define OpAccHi 30ull /* High part of extended acc (-/DX/EDX/RDX) */ | ||
64 | 66 | ||
65 | #define OpBits 5 /* Width of operand field */ | 67 | #define OpBits 5 /* Width of operand field */ |
66 | #define OpMask ((1ull << OpBits) - 1) | 68 | #define OpMask ((1ull << OpBits) - 1) |
@@ -86,6 +88,7 @@ | |||
86 | #define DstMem64 (OpMem64 << DstShift) | 88 | #define DstMem64 (OpMem64 << DstShift) |
87 | #define DstImmUByte (OpImmUByte << DstShift) | 89 | #define DstImmUByte (OpImmUByte << DstShift) |
88 | #define DstDX (OpDX << DstShift) | 90 | #define DstDX (OpDX << DstShift) |
91 | #define DstAccLo (OpAccLo << DstShift) | ||
89 | #define DstMask (OpMask << DstShift) | 92 | #define DstMask (OpMask << DstShift) |
90 | /* Source operand type. */ | 93 | /* Source operand type. */ |
91 | #define SrcShift 6 | 94 | #define SrcShift 6 |
@@ -108,6 +111,7 @@ | |||
108 | #define SrcImm64 (OpImm64 << SrcShift) | 111 | #define SrcImm64 (OpImm64 << SrcShift) |
109 | #define SrcDX (OpDX << SrcShift) | 112 | #define SrcDX (OpDX << SrcShift) |
110 | #define SrcMem8 (OpMem8 << SrcShift) | 113 | #define SrcMem8 (OpMem8 << SrcShift) |
114 | #define SrcAccHi (OpAccHi << SrcShift) | ||
111 | #define SrcMask (OpMask << SrcShift) | 115 | #define SrcMask (OpMask << SrcShift) |
112 | #define BitOp (1<<11) | 116 | #define BitOp (1<<11) |
113 | #define MemAbs (1<<12) /* Memory operand is absolute displacement */ | 117 | #define MemAbs (1<<12) /* Memory operand is absolute displacement */ |
@@ -138,6 +142,7 @@ | |||
138 | /* Source 2 operand type */ | 142 | /* Source 2 operand type */ |
139 | #define Src2Shift (31) | 143 | #define Src2Shift (31) |
140 | #define Src2None (OpNone << Src2Shift) | 144 | #define Src2None (OpNone << Src2Shift) |
145 | #define Src2Mem (OpMem << Src2Shift) | ||
141 | #define Src2CL (OpCL << Src2Shift) | 146 | #define Src2CL (OpCL << Src2Shift) |
142 | #define Src2ImmByte (OpImmByte << Src2Shift) | 147 | #define Src2ImmByte (OpImmByte << Src2Shift) |
143 | #define Src2One (OpOne << Src2Shift) | 148 | #define Src2One (OpOne << Src2Shift) |
@@ -155,6 +160,9 @@ | |||
155 | #define Avx ((u64)1 << 43) /* Advanced Vector Extensions */ | 160 | #define Avx ((u64)1 << 43) /* Advanced Vector Extensions */ |
156 | #define Fastop ((u64)1 << 44) /* Use opcode::u.fastop */ | 161 | #define Fastop ((u64)1 << 44) /* Use opcode::u.fastop */ |
157 | #define NoWrite ((u64)1 << 45) /* No writeback */ | 162 | #define NoWrite ((u64)1 << 45) /* No writeback */ |
163 | #define SrcWrite ((u64)1 << 46) /* Write back src operand */ | ||
164 | |||
165 | #define DstXacc (DstAccLo | SrcAccHi | SrcWrite) | ||
158 | 166 | ||
159 | #define X2(x...) x, x | 167 | #define X2(x...) x, x |
160 | #define X3(x...) X2(x), x | 168 | #define X3(x...) X2(x), x |
@@ -171,10 +179,11 @@ | |||
171 | /* | 179 | /* |
172 | * fastop functions have a special calling convention: | 180 | * fastop functions have a special calling convention: |
173 | * | 181 | * |
174 | * dst: [rdx]:rax (in/out) | 182 | * dst: rax (in/out) |
175 | * src: rbx (in/out) | 183 | * src: rdx (in/out) |
176 | * src2: rcx (in) | 184 | * src2: rcx (in) |
177 | * flags: rflags (in/out) | 185 | * flags: rflags (in/out) |
186 | * ex: rsi (in:fastop pointer, out:zero if exception) | ||
178 | * | 187 | * |
179 | * Moreover, they are all exactly FASTOP_SIZE bytes long, so functions for | 188 | * Moreover, they are all exactly FASTOP_SIZE bytes long, so functions for |
180 | * different operand sizes can be reached by calculation, rather than a jump | 189 | * different operand sizes can be reached by calculation, rather than a jump |
@@ -276,174 +285,17 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) | |||
276 | } | 285 | } |
277 | 286 | ||
278 | /* | 287 | /* |
279 | * Instruction emulation: | ||
280 | * Most instructions are emulated directly via a fragment of inline assembly | ||
281 | * code. This allows us to save/restore EFLAGS and thus very easily pick up | ||
282 | * any modified flags. | ||
283 | */ | ||
284 | |||
285 | #if defined(CONFIG_X86_64) | ||
286 | #define _LO32 "k" /* force 32-bit operand */ | ||
287 | #define _STK "%%rsp" /* stack pointer */ | ||
288 | #elif defined(__i386__) | ||
289 | #define _LO32 "" /* force 32-bit operand */ | ||
290 | #define _STK "%%esp" /* stack pointer */ | ||
291 | #endif | ||
292 | |||
293 | /* | ||
294 | * These EFLAGS bits are restored from saved value during emulation, and | 288 | * These EFLAGS bits are restored from saved value during emulation, and |
295 | * any changes are written back to the saved value after emulation. | 289 | * any changes are written back to the saved value after emulation. |
296 | */ | 290 | */ |
297 | #define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF) | 291 | #define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF) |
298 | 292 | ||
299 | /* Before executing instruction: restore necessary bits in EFLAGS. */ | ||
300 | #define _PRE_EFLAGS(_sav, _msk, _tmp) \ | ||
301 | /* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \ | ||
302 | "movl %"_sav",%"_LO32 _tmp"; " \ | ||
303 | "push %"_tmp"; " \ | ||
304 | "push %"_tmp"; " \ | ||
305 | "movl %"_msk",%"_LO32 _tmp"; " \ | ||
306 | "andl %"_LO32 _tmp",("_STK"); " \ | ||
307 | "pushf; " \ | ||
308 | "notl %"_LO32 _tmp"; " \ | ||
309 | "andl %"_LO32 _tmp",("_STK"); " \ | ||
310 | "andl %"_LO32 _tmp","__stringify(BITS_PER_LONG/4)"("_STK"); " \ | ||
311 | "pop %"_tmp"; " \ | ||
312 | "orl %"_LO32 _tmp",("_STK"); " \ | ||
313 | "popf; " \ | ||
314 | "pop %"_sav"; " | ||
315 | |||
316 | /* After executing instruction: write-back necessary bits in EFLAGS. */ | ||
317 | #define _POST_EFLAGS(_sav, _msk, _tmp) \ | ||
318 | /* _sav |= EFLAGS & _msk; */ \ | ||
319 | "pushf; " \ | ||
320 | "pop %"_tmp"; " \ | ||
321 | "andl %"_msk",%"_LO32 _tmp"; " \ | ||
322 | "orl %"_LO32 _tmp",%"_sav"; " | ||
323 | |||
324 | #ifdef CONFIG_X86_64 | 293 | #ifdef CONFIG_X86_64 |
325 | #define ON64(x) x | 294 | #define ON64(x) x |
326 | #else | 295 | #else |
327 | #define ON64(x) | 296 | #define ON64(x) |
328 | #endif | 297 | #endif |
329 | 298 | ||
330 | #define ____emulate_2op(ctxt, _op, _x, _y, _suffix, _dsttype) \ | ||
331 | do { \ | ||
332 | __asm__ __volatile__ ( \ | ||
333 | _PRE_EFLAGS("0", "4", "2") \ | ||
334 | _op _suffix " %"_x"3,%1; " \ | ||
335 | _POST_EFLAGS("0", "4", "2") \ | ||
336 | : "=m" ((ctxt)->eflags), \ | ||
337 | "+q" (*(_dsttype*)&(ctxt)->dst.val), \ | ||
338 | "=&r" (_tmp) \ | ||
339 | : _y ((ctxt)->src.val), "i" (EFLAGS_MASK)); \ | ||
340 | } while (0) | ||
341 | |||
342 | |||
343 | /* Raw emulation: instruction has two explicit operands. */ | ||
344 | #define __emulate_2op_nobyte(ctxt,_op,_wx,_wy,_lx,_ly,_qx,_qy) \ | ||
345 | do { \ | ||
346 | unsigned long _tmp; \ | ||
347 | \ | ||
348 | switch ((ctxt)->dst.bytes) { \ | ||
349 | case 2: \ | ||
350 | ____emulate_2op(ctxt,_op,_wx,_wy,"w",u16); \ | ||
351 | break; \ | ||
352 | case 4: \ | ||
353 | ____emulate_2op(ctxt,_op,_lx,_ly,"l",u32); \ | ||
354 | break; \ | ||
355 | case 8: \ | ||
356 | ON64(____emulate_2op(ctxt,_op,_qx,_qy,"q",u64)); \ | ||
357 | break; \ | ||
358 | } \ | ||
359 | } while (0) | ||
360 | |||
361 | #define __emulate_2op(ctxt,_op,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ | ||
362 | do { \ | ||
363 | unsigned long _tmp; \ | ||
364 | switch ((ctxt)->dst.bytes) { \ | ||
365 | case 1: \ | ||
366 | ____emulate_2op(ctxt,_op,_bx,_by,"b",u8); \ | ||
367 | break; \ | ||
368 | default: \ | ||
369 | __emulate_2op_nobyte(ctxt, _op, \ | ||
370 | _wx, _wy, _lx, _ly, _qx, _qy); \ | ||
371 | break; \ | ||
372 | } \ | ||
373 | } while (0) | ||
374 | |||
375 | /* Source operand is byte-sized and may be restricted to just %cl. */ | ||
376 | #define emulate_2op_SrcB(ctxt, _op) \ | ||
377 | __emulate_2op(ctxt, _op, "b", "c", "b", "c", "b", "c", "b", "c") | ||
378 | |||
379 | /* Source operand is byte, word, long or quad sized. */ | ||
380 | #define emulate_2op_SrcV(ctxt, _op) \ | ||
381 | __emulate_2op(ctxt, _op, "b", "q", "w", "r", _LO32, "r", "", "r") | ||
382 | |||
383 | /* Source operand is word, long or quad sized. */ | ||
384 | #define emulate_2op_SrcV_nobyte(ctxt, _op) \ | ||
385 | __emulate_2op_nobyte(ctxt, _op, "w", "r", _LO32, "r", "", "r") | ||
386 | |||
387 | /* Instruction has three operands and one operand is stored in ECX register */ | ||
388 | #define __emulate_2op_cl(ctxt, _op, _suffix, _type) \ | ||
389 | do { \ | ||
390 | unsigned long _tmp; \ | ||
391 | _type _clv = (ctxt)->src2.val; \ | ||
392 | _type _srcv = (ctxt)->src.val; \ | ||
393 | _type _dstv = (ctxt)->dst.val; \ | ||
394 | \ | ||
395 | __asm__ __volatile__ ( \ | ||
396 | _PRE_EFLAGS("0", "5", "2") \ | ||
397 | _op _suffix " %4,%1 \n" \ | ||
398 | _POST_EFLAGS("0", "5", "2") \ | ||
399 | : "=m" ((ctxt)->eflags), "+r" (_dstv), "=&r" (_tmp) \ | ||
400 | : "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK) \ | ||
401 | ); \ | ||
402 | \ | ||
403 | (ctxt)->src2.val = (unsigned long) _clv; \ | ||
404 | (ctxt)->src2.val = (unsigned long) _srcv; \ | ||
405 | (ctxt)->dst.val = (unsigned long) _dstv; \ | ||
406 | } while (0) | ||
407 | |||
408 | #define emulate_2op_cl(ctxt, _op) \ | ||
409 | do { \ | ||
410 | switch ((ctxt)->dst.bytes) { \ | ||
411 | case 2: \ | ||
412 | __emulate_2op_cl(ctxt, _op, "w", u16); \ | ||
413 | break; \ | ||
414 | case 4: \ | ||
415 | __emulate_2op_cl(ctxt, _op, "l", u32); \ | ||
416 | break; \ | ||
417 | case 8: \ | ||
418 | ON64(__emulate_2op_cl(ctxt, _op, "q", ulong)); \ | ||
419 | break; \ | ||
420 | } \ | ||
421 | } while (0) | ||
422 | |||
423 | #define __emulate_1op(ctxt, _op, _suffix) \ | ||
424 | do { \ | ||
425 | unsigned long _tmp; \ | ||
426 | \ | ||
427 | __asm__ __volatile__ ( \ | ||
428 | _PRE_EFLAGS("0", "3", "2") \ | ||
429 | _op _suffix " %1; " \ | ||
430 | _POST_EFLAGS("0", "3", "2") \ | ||
431 | : "=m" ((ctxt)->eflags), "+m" ((ctxt)->dst.val), \ | ||
432 | "=&r" (_tmp) \ | ||
433 | : "i" (EFLAGS_MASK)); \ | ||
434 | } while (0) | ||
435 | |||
436 | /* Instruction has only one explicit operand (no source operand). */ | ||
437 | #define emulate_1op(ctxt, _op) \ | ||
438 | do { \ | ||
439 | switch ((ctxt)->dst.bytes) { \ | ||
440 | case 1: __emulate_1op(ctxt, _op, "b"); break; \ | ||
441 | case 2: __emulate_1op(ctxt, _op, "w"); break; \ | ||
442 | case 4: __emulate_1op(ctxt, _op, "l"); break; \ | ||
443 | case 8: ON64(__emulate_1op(ctxt, _op, "q")); break; \ | ||
444 | } \ | ||
445 | } while (0) | ||
446 | |||
447 | static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | 299 | static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); |
448 | 300 | ||
449 | #define FOP_ALIGN ".align " __stringify(FASTOP_SIZE) " \n\t" | 301 | #define FOP_ALIGN ".align " __stringify(FASTOP_SIZE) " \n\t" |
@@ -462,7 +314,10 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | |||
462 | #define FOPNOP() FOP_ALIGN FOP_RET | 314 | #define FOPNOP() FOP_ALIGN FOP_RET |
463 | 315 | ||
464 | #define FOP1E(op, dst) \ | 316 | #define FOP1E(op, dst) \ |
465 | FOP_ALIGN #op " %" #dst " \n\t" FOP_RET | 317 | FOP_ALIGN "10: " #op " %" #dst " \n\t" FOP_RET |
318 | |||
319 | #define FOP1EEX(op, dst) \ | ||
320 | FOP1E(op, dst) _ASM_EXTABLE(10b, kvm_fastop_exception) | ||
466 | 321 | ||
467 | #define FASTOP1(op) \ | 322 | #define FASTOP1(op) \ |
468 | FOP_START(op) \ | 323 | FOP_START(op) \ |
@@ -472,24 +327,42 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | |||
472 | ON64(FOP1E(op##q, rax)) \ | 327 | ON64(FOP1E(op##q, rax)) \ |
473 | FOP_END | 328 | FOP_END |
474 | 329 | ||
330 | /* 1-operand, using src2 (for MUL/DIV r/m) */ | ||
331 | #define FASTOP1SRC2(op, name) \ | ||
332 | FOP_START(name) \ | ||
333 | FOP1E(op, cl) \ | ||
334 | FOP1E(op, cx) \ | ||
335 | FOP1E(op, ecx) \ | ||
336 | ON64(FOP1E(op, rcx)) \ | ||
337 | FOP_END | ||
338 | |||
339 | /* 1-operand, using src2 (for MUL/DIV r/m), with exceptions */ | ||
340 | #define FASTOP1SRC2EX(op, name) \ | ||
341 | FOP_START(name) \ | ||
342 | FOP1EEX(op, cl) \ | ||
343 | FOP1EEX(op, cx) \ | ||
344 | FOP1EEX(op, ecx) \ | ||
345 | ON64(FOP1EEX(op, rcx)) \ | ||
346 | FOP_END | ||
347 | |||
475 | #define FOP2E(op, dst, src) \ | 348 | #define FOP2E(op, dst, src) \ |
476 | FOP_ALIGN #op " %" #src ", %" #dst " \n\t" FOP_RET | 349 | FOP_ALIGN #op " %" #src ", %" #dst " \n\t" FOP_RET |
477 | 350 | ||
478 | #define FASTOP2(op) \ | 351 | #define FASTOP2(op) \ |
479 | FOP_START(op) \ | 352 | FOP_START(op) \ |
480 | FOP2E(op##b, al, bl) \ | 353 | FOP2E(op##b, al, dl) \ |
481 | FOP2E(op##w, ax, bx) \ | 354 | FOP2E(op##w, ax, dx) \ |
482 | FOP2E(op##l, eax, ebx) \ | 355 | FOP2E(op##l, eax, edx) \ |
483 | ON64(FOP2E(op##q, rax, rbx)) \ | 356 | ON64(FOP2E(op##q, rax, rdx)) \ |
484 | FOP_END | 357 | FOP_END |
485 | 358 | ||
486 | /* 2 operand, word only */ | 359 | /* 2 operand, word only */ |
487 | #define FASTOP2W(op) \ | 360 | #define FASTOP2W(op) \ |
488 | FOP_START(op) \ | 361 | FOP_START(op) \ |
489 | FOPNOP() \ | 362 | FOPNOP() \ |
490 | FOP2E(op##w, ax, bx) \ | 363 | FOP2E(op##w, ax, dx) \ |
491 | FOP2E(op##l, eax, ebx) \ | 364 | FOP2E(op##l, eax, edx) \ |
492 | ON64(FOP2E(op##q, rax, rbx)) \ | 365 | ON64(FOP2E(op##q, rax, rdx)) \ |
493 | FOP_END | 366 | FOP_END |
494 | 367 | ||
495 | /* 2 operand, src is CL */ | 368 | /* 2 operand, src is CL */ |
@@ -508,14 +381,17 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); | |||
508 | #define FASTOP3WCL(op) \ | 381 | #define FASTOP3WCL(op) \ |
509 | FOP_START(op) \ | 382 | FOP_START(op) \ |
510 | FOPNOP() \ | 383 | FOPNOP() \ |
511 | FOP3E(op##w, ax, bx, cl) \ | 384 | FOP3E(op##w, ax, dx, cl) \ |
512 | FOP3E(op##l, eax, ebx, cl) \ | 385 | FOP3E(op##l, eax, edx, cl) \ |
513 | ON64(FOP3E(op##q, rax, rbx, cl)) \ | 386 | ON64(FOP3E(op##q, rax, rdx, cl)) \ |
514 | FOP_END | 387 | FOP_END |
515 | 388 | ||
516 | /* Special case for SETcc - 1 instruction per cc */ | 389 | /* Special case for SETcc - 1 instruction per cc */ |
517 | #define FOP_SETCC(op) ".align 4; " #op " %al; ret \n\t" | 390 | #define FOP_SETCC(op) ".align 4; " #op " %al; ret \n\t" |
518 | 391 | ||
392 | asm(".global kvm_fastop_exception \n" | ||
393 | "kvm_fastop_exception: xor %esi, %esi; ret"); | ||
394 | |||
519 | FOP_START(setcc) | 395 | FOP_START(setcc) |
520 | FOP_SETCC(seto) | 396 | FOP_SETCC(seto) |
521 | FOP_SETCC(setno) | 397 | FOP_SETCC(setno) |
@@ -538,47 +414,6 @@ FOP_END; | |||
538 | FOP_START(salc) "pushf; sbb %al, %al; popf \n\t" FOP_RET | 414 | FOP_START(salc) "pushf; sbb %al, %al; popf \n\t" FOP_RET |
539 | FOP_END; | 415 | FOP_END; |
540 | 416 | ||
541 | #define __emulate_1op_rax_rdx(ctxt, _op, _suffix, _ex) \ | ||
542 | do { \ | ||
543 | unsigned long _tmp; \ | ||
544 | ulong *rax = reg_rmw((ctxt), VCPU_REGS_RAX); \ | ||
545 | ulong *rdx = reg_rmw((ctxt), VCPU_REGS_RDX); \ | ||
546 | \ | ||
547 | __asm__ __volatile__ ( \ | ||
548 | _PRE_EFLAGS("0", "5", "1") \ | ||
549 | "1: \n\t" \ | ||
550 | _op _suffix " %6; " \ | ||
551 | "2: \n\t" \ | ||
552 | _POST_EFLAGS("0", "5", "1") \ | ||
553 | ".pushsection .fixup,\"ax\" \n\t" \ | ||
554 | "3: movb $1, %4 \n\t" \ | ||
555 | "jmp 2b \n\t" \ | ||
556 | ".popsection \n\t" \ | ||
557 | _ASM_EXTABLE(1b, 3b) \ | ||
558 | : "=m" ((ctxt)->eflags), "=&r" (_tmp), \ | ||
559 | "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \ | ||
560 | : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \ | ||
561 | } while (0) | ||
562 | |||
563 | /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ | ||
564 | #define emulate_1op_rax_rdx(ctxt, _op, _ex) \ | ||
565 | do { \ | ||
566 | switch((ctxt)->src.bytes) { \ | ||
567 | case 1: \ | ||
568 | __emulate_1op_rax_rdx(ctxt, _op, "b", _ex); \ | ||
569 | break; \ | ||
570 | case 2: \ | ||
571 | __emulate_1op_rax_rdx(ctxt, _op, "w", _ex); \ | ||
572 | break; \ | ||
573 | case 4: \ | ||
574 | __emulate_1op_rax_rdx(ctxt, _op, "l", _ex); \ | ||
575 | break; \ | ||
576 | case 8: ON64( \ | ||
577 | __emulate_1op_rax_rdx(ctxt, _op, "q", _ex)); \ | ||
578 | break; \ | ||
579 | } \ | ||
580 | } while (0) | ||
581 | |||
582 | static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt, | 417 | static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt, |
583 | enum x86_intercept intercept, | 418 | enum x86_intercept intercept, |
584 | enum x86_intercept_stage stage) | 419 | enum x86_intercept_stage stage) |
@@ -988,6 +823,11 @@ FASTOP2(xor); | |||
988 | FASTOP2(cmp); | 823 | FASTOP2(cmp); |
989 | FASTOP2(test); | 824 | FASTOP2(test); |
990 | 825 | ||
826 | FASTOP1SRC2(mul, mul_ex); | ||
827 | FASTOP1SRC2(imul, imul_ex); | ||
828 | FASTOP1SRC2EX(div, div_ex); | ||
829 | FASTOP1SRC2EX(idiv, idiv_ex); | ||
830 | |||
991 | FASTOP3WCL(shld); | 831 | FASTOP3WCL(shld); |
992 | FASTOP3WCL(shrd); | 832 | FASTOP3WCL(shrd); |
993 | 833 | ||
@@ -1013,6 +853,8 @@ FASTOP2W(bts); | |||
1013 | FASTOP2W(btr); | 853 | FASTOP2W(btr); |
1014 | FASTOP2W(btc); | 854 | FASTOP2W(btc); |
1015 | 855 | ||
856 | FASTOP2(xadd); | ||
857 | |||
1016 | static u8 test_cc(unsigned int condition, unsigned long flags) | 858 | static u8 test_cc(unsigned int condition, unsigned long flags) |
1017 | { | 859 | { |
1018 | u8 rc; | 860 | u8 rc; |
@@ -1726,45 +1568,42 @@ static void write_register_operand(struct operand *op) | |||
1726 | } | 1568 | } |
1727 | } | 1569 | } |
1728 | 1570 | ||
1729 | static int writeback(struct x86_emulate_ctxt *ctxt) | 1571 | static int writeback(struct x86_emulate_ctxt *ctxt, struct operand *op) |
1730 | { | 1572 | { |
1731 | int rc; | 1573 | int rc; |
1732 | 1574 | ||
1733 | if (ctxt->d & NoWrite) | 1575 | switch (op->type) { |
1734 | return X86EMUL_CONTINUE; | ||
1735 | |||
1736 | switch (ctxt->dst.type) { | ||
1737 | case OP_REG: | 1576 | case OP_REG: |
1738 | write_register_operand(&ctxt->dst); | 1577 | write_register_operand(op); |
1739 | break; | 1578 | break; |
1740 | case OP_MEM: | 1579 | case OP_MEM: |
1741 | if (ctxt->lock_prefix) | 1580 | if (ctxt->lock_prefix) |
1742 | rc = segmented_cmpxchg(ctxt, | 1581 | rc = segmented_cmpxchg(ctxt, |
1743 | ctxt->dst.addr.mem, | 1582 | op->addr.mem, |
1744 | &ctxt->dst.orig_val, | 1583 | &op->orig_val, |
1745 | &ctxt->dst.val, | 1584 | &op->val, |
1746 | ctxt->dst.bytes); | 1585 | op->bytes); |
1747 | else | 1586 | else |
1748 | rc = segmented_write(ctxt, | 1587 | rc = segmented_write(ctxt, |
1749 | ctxt->dst.addr.mem, | 1588 | op->addr.mem, |
1750 | &ctxt->dst.val, | 1589 | &op->val, |
1751 | ctxt->dst.bytes); | 1590 | op->bytes); |
1752 | if (rc != X86EMUL_CONTINUE) | 1591 | if (rc != X86EMUL_CONTINUE) |
1753 | return rc; | 1592 | return rc; |
1754 | break; | 1593 | break; |
1755 | case OP_MEM_STR: | 1594 | case OP_MEM_STR: |
1756 | rc = segmented_write(ctxt, | 1595 | rc = segmented_write(ctxt, |
1757 | ctxt->dst.addr.mem, | 1596 | op->addr.mem, |
1758 | ctxt->dst.data, | 1597 | op->data, |
1759 | ctxt->dst.bytes * ctxt->dst.count); | 1598 | op->bytes * op->count); |
1760 | if (rc != X86EMUL_CONTINUE) | 1599 | if (rc != X86EMUL_CONTINUE) |
1761 | return rc; | 1600 | return rc; |
1762 | break; | 1601 | break; |
1763 | case OP_XMM: | 1602 | case OP_XMM: |
1764 | write_sse_reg(ctxt, &ctxt->dst.vec_val, ctxt->dst.addr.xmm); | 1603 | write_sse_reg(ctxt, &op->vec_val, op->addr.xmm); |
1765 | break; | 1604 | break; |
1766 | case OP_MM: | 1605 | case OP_MM: |
1767 | write_mmx_reg(ctxt, &ctxt->dst.mm_val, ctxt->dst.addr.mm); | 1606 | write_mmx_reg(ctxt, &op->mm_val, op->addr.mm); |
1768 | break; | 1607 | break; |
1769 | case OP_NONE: | 1608 | case OP_NONE: |
1770 | /* no writeback */ | 1609 | /* no writeback */ |
@@ -2117,42 +1956,6 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt) | |||
2117 | return X86EMUL_CONTINUE; | 1956 | return X86EMUL_CONTINUE; |
2118 | } | 1957 | } |
2119 | 1958 | ||
2120 | static int em_mul_ex(struct x86_emulate_ctxt *ctxt) | ||
2121 | { | ||
2122 | u8 ex = 0; | ||
2123 | |||
2124 | emulate_1op_rax_rdx(ctxt, "mul", ex); | ||
2125 | return X86EMUL_CONTINUE; | ||
2126 | } | ||
2127 | |||
2128 | static int em_imul_ex(struct x86_emulate_ctxt *ctxt) | ||
2129 | { | ||
2130 | u8 ex = 0; | ||
2131 | |||
2132 | emulate_1op_rax_rdx(ctxt, "imul", ex); | ||
2133 | return X86EMUL_CONTINUE; | ||
2134 | } | ||
2135 | |||
2136 | static int em_div_ex(struct x86_emulate_ctxt *ctxt) | ||
2137 | { | ||
2138 | u8 de = 0; | ||
2139 | |||
2140 | emulate_1op_rax_rdx(ctxt, "div", de); | ||
2141 | if (de) | ||
2142 | return emulate_de(ctxt); | ||
2143 | return X86EMUL_CONTINUE; | ||
2144 | } | ||
2145 | |||
2146 | static int em_idiv_ex(struct x86_emulate_ctxt *ctxt) | ||
2147 | { | ||
2148 | u8 de = 0; | ||
2149 | |||
2150 | emulate_1op_rax_rdx(ctxt, "idiv", de); | ||
2151 | if (de) | ||
2152 | return emulate_de(ctxt); | ||
2153 | return X86EMUL_CONTINUE; | ||
2154 | } | ||
2155 | |||
2156 | static int em_grp45(struct x86_emulate_ctxt *ctxt) | 1959 | static int em_grp45(struct x86_emulate_ctxt *ctxt) |
2157 | { | 1960 | { |
2158 | int rc = X86EMUL_CONTINUE; | 1961 | int rc = X86EMUL_CONTINUE; |
@@ -3734,10 +3537,10 @@ static const struct opcode group3[] = { | |||
3734 | F(DstMem | SrcImm | NoWrite, em_test), | 3537 | F(DstMem | SrcImm | NoWrite, em_test), |
3735 | F(DstMem | SrcNone | Lock, em_not), | 3538 | F(DstMem | SrcNone | Lock, em_not), |
3736 | F(DstMem | SrcNone | Lock, em_neg), | 3539 | F(DstMem | SrcNone | Lock, em_neg), |
3737 | I(SrcMem, em_mul_ex), | 3540 | F(DstXacc | Src2Mem, em_mul_ex), |
3738 | I(SrcMem, em_imul_ex), | 3541 | F(DstXacc | Src2Mem, em_imul_ex), |
3739 | I(SrcMem, em_div_ex), | 3542 | F(DstXacc | Src2Mem, em_div_ex), |
3740 | I(SrcMem, em_idiv_ex), | 3543 | F(DstXacc | Src2Mem, em_idiv_ex), |
3741 | }; | 3544 | }; |
3742 | 3545 | ||
3743 | static const struct opcode group4[] = { | 3546 | static const struct opcode group4[] = { |
@@ -4064,7 +3867,7 @@ static const struct opcode twobyte_table[256] = { | |||
4064 | F(DstReg | SrcMem | ModRM, em_bsf), F(DstReg | SrcMem | ModRM, em_bsr), | 3867 | F(DstReg | SrcMem | ModRM, em_bsf), F(DstReg | SrcMem | ModRM, em_bsr), |
4065 | D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), | 3868 | D(DstReg | SrcMem8 | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), |
4066 | /* 0xC0 - 0xC7 */ | 3869 | /* 0xC0 - 0xC7 */ |
4067 | D2bv(DstMem | SrcReg | ModRM | Lock), | 3870 | F2bv(DstMem | SrcReg | ModRM | SrcWrite | Lock, em_xadd), |
4068 | N, D(DstMem | SrcReg | ModRM | Mov), | 3871 | N, D(DstMem | SrcReg | ModRM | Mov), |
4069 | N, N, N, GD(0, &group9), | 3872 | N, N, N, GD(0, &group9), |
4070 | /* 0xC8 - 0xCF */ | 3873 | /* 0xC8 - 0xCF */ |
@@ -4172,6 +3975,24 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op, | |||
4172 | fetch_register_operand(op); | 3975 | fetch_register_operand(op); |
4173 | op->orig_val = op->val; | 3976 | op->orig_val = op->val; |
4174 | break; | 3977 | break; |
3978 | case OpAccLo: | ||
3979 | op->type = OP_REG; | ||
3980 | op->bytes = (ctxt->d & ByteOp) ? 2 : ctxt->op_bytes; | ||
3981 | op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX); | ||
3982 | fetch_register_operand(op); | ||
3983 | op->orig_val = op->val; | ||
3984 | break; | ||
3985 | case OpAccHi: | ||
3986 | if (ctxt->d & ByteOp) { | ||
3987 | op->type = OP_NONE; | ||
3988 | break; | ||
3989 | } | ||
3990 | op->type = OP_REG; | ||
3991 | op->bytes = ctxt->op_bytes; | ||
3992 | op->addr.reg = reg_rmw(ctxt, VCPU_REGS_RDX); | ||
3993 | fetch_register_operand(op); | ||
3994 | op->orig_val = op->val; | ||
3995 | break; | ||
4175 | case OpDI: | 3996 | case OpDI: |
4176 | op->type = OP_MEM; | 3997 | op->type = OP_MEM; |
4177 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; | 3998 | op->bytes = (ctxt->d & ByteOp) ? 1 : ctxt->op_bytes; |
@@ -4553,11 +4374,15 @@ static void fetch_possible_mmx_operand(struct x86_emulate_ctxt *ctxt, | |||
4553 | static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)) | 4374 | static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)) |
4554 | { | 4375 | { |
4555 | ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF; | 4376 | ulong flags = (ctxt->eflags & EFLAGS_MASK) | X86_EFLAGS_IF; |
4556 | fop += __ffs(ctxt->dst.bytes) * FASTOP_SIZE; | 4377 | if (!(ctxt->d & ByteOp)) |
4378 | fop += __ffs(ctxt->dst.bytes) * FASTOP_SIZE; | ||
4557 | asm("push %[flags]; popf; call *%[fastop]; pushf; pop %[flags]\n" | 4379 | asm("push %[flags]; popf; call *%[fastop]; pushf; pop %[flags]\n" |
4558 | : "+a"(ctxt->dst.val), "+b"(ctxt->src.val), [flags]"+D"(flags) | 4380 | : "+a"(ctxt->dst.val), "+d"(ctxt->src.val), [flags]"+D"(flags), |
4559 | : "c"(ctxt->src2.val), [fastop]"S"(fop)); | 4381 | [fastop]"+S"(fop) |
4382 | : "c"(ctxt->src2.val)); | ||
4560 | ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK); | 4383 | ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK); |
4384 | if (!fop) /* exception is returned in fop variable */ | ||
4385 | return emulate_de(ctxt); | ||
4561 | return X86EMUL_CONTINUE; | 4386 | return X86EMUL_CONTINUE; |
4562 | } | 4387 | } |
4563 | 4388 | ||
@@ -4773,9 +4598,17 @@ special_insn: | |||
4773 | goto done; | 4598 | goto done; |
4774 | 4599 | ||
4775 | writeback: | 4600 | writeback: |
4776 | rc = writeback(ctxt); | 4601 | if (!(ctxt->d & NoWrite)) { |
4777 | if (rc != X86EMUL_CONTINUE) | 4602 | rc = writeback(ctxt, &ctxt->dst); |
4778 | goto done; | 4603 | if (rc != X86EMUL_CONTINUE) |
4604 | goto done; | ||
4605 | } | ||
4606 | if (ctxt->d & SrcWrite) { | ||
4607 | BUG_ON(ctxt->src.type == OP_MEM || ctxt->src.type == OP_MEM_STR); | ||
4608 | rc = writeback(ctxt, &ctxt->src); | ||
4609 | if (rc != X86EMUL_CONTINUE) | ||
4610 | goto done; | ||
4611 | } | ||
4779 | 4612 | ||
4780 | /* | 4613 | /* |
4781 | * restore dst type in case the decoding will be reused | 4614 | * restore dst type in case the decoding will be reused |
@@ -4872,12 +4705,6 @@ twobyte_insn: | |||
4872 | ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val : | 4705 | ctxt->dst.val = (ctxt->src.bytes == 1) ? (s8) ctxt->src.val : |
4873 | (s16) ctxt->src.val; | 4706 | (s16) ctxt->src.val; |
4874 | break; | 4707 | break; |
4875 | case 0xc0 ... 0xc1: /* xadd */ | ||
4876 | fastop(ctxt, em_add); | ||
4877 | /* Write back the register source. */ | ||
4878 | ctxt->src.val = ctxt->dst.orig_val; | ||
4879 | write_register_operand(&ctxt->src); | ||
4880 | break; | ||
4881 | case 0xc3: /* movnti */ | 4708 | case 0xc3: /* movnti */ |
4882 | ctxt->dst.bytes = ctxt->op_bytes; | 4709 | ctxt->dst.bytes = ctxt->op_bytes; |
4883 | ctxt->dst.val = (ctxt->op_bytes == 4) ? (u32) ctxt->src.val : | 4710 | ctxt->dst.val = (ctxt->op_bytes == 4) ? (u32) ctxt->src.val : |