diff options
author | Avi Kivity <avi.kivity@gmail.com> | 2013-02-09 04:31:50 -0500 |
---|---|---|
committer | Gleb Natapov <gleb@redhat.com> | 2013-05-21 08:43:23 -0400 |
commit | 203831e8e4bd9ab3b2f9f86c73c74fe912e06ac5 (patch) | |
tree | 6e297a55e0cebfe9b7b1c18eeeb3ddea54aa8185 /arch | |
parent | b8c0b6ae498fe5c3f29966bd2a2d9882911b887b (diff) |
KVM: x86 emulator: drop unused old-style inline emulation
Signed-off-by: Avi Kivity <avi.kivity@gmail.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/emulate.c | 198 |
1 files changed, 0 insertions, 198 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8404dc350988..d71aac0bf32f 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -285,174 +285,17 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) | |||
285 | } | 285 | } |
286 | 286 | ||
287 | /* | 287 | /* |
288 | * Instruction emulation: | ||
289 | * Most instructions are emulated directly via a fragment of inline assembly | ||
290 | * code. This allows us to save/restore EFLAGS and thus very easily pick up | ||
291 | * any modified flags. | ||
292 | */ | ||
293 | |||
294 | #if defined(CONFIG_X86_64) | ||
295 | #define _LO32 "k" /* force 32-bit operand */ | ||
296 | #define _STK "%%rsp" /* stack pointer */ | ||
297 | #elif defined(__i386__) | ||
298 | #define _LO32 "" /* force 32-bit operand */ | ||
299 | #define _STK "%%esp" /* stack pointer */ | ||
300 | #endif | ||
301 | |||
302 | /* | ||
303 | * These EFLAGS bits are restored from saved value during emulation, and | 288 | * These EFLAGS bits are restored from saved value during emulation, and |
304 | * any changes are written back to the saved value after emulation. | 289 | * any changes are written back to the saved value after emulation. |
305 | */ | 290 | */ |
306 | #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) |
307 | 292 | ||
308 | /* Before executing instruction: restore necessary bits in EFLAGS. */ | ||
309 | #define _PRE_EFLAGS(_sav, _msk, _tmp) \ | ||
310 | /* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \ | ||
311 | "movl %"_sav",%"_LO32 _tmp"; " \ | ||
312 | "push %"_tmp"; " \ | ||
313 | "push %"_tmp"; " \ | ||
314 | "movl %"_msk",%"_LO32 _tmp"; " \ | ||
315 | "andl %"_LO32 _tmp",("_STK"); " \ | ||
316 | "pushf; " \ | ||
317 | "notl %"_LO32 _tmp"; " \ | ||
318 | "andl %"_LO32 _tmp",("_STK"); " \ | ||
319 | "andl %"_LO32 _tmp","__stringify(BITS_PER_LONG/4)"("_STK"); " \ | ||
320 | "pop %"_tmp"; " \ | ||
321 | "orl %"_LO32 _tmp",("_STK"); " \ | ||
322 | "popf; " \ | ||
323 | "pop %"_sav"; " | ||
324 | |||
325 | /* After executing instruction: write-back necessary bits in EFLAGS. */ | ||
326 | #define _POST_EFLAGS(_sav, _msk, _tmp) \ | ||
327 | /* _sav |= EFLAGS & _msk; */ \ | ||
328 | "pushf; " \ | ||
329 | "pop %"_tmp"; " \ | ||
330 | "andl %"_msk",%"_LO32 _tmp"; " \ | ||
331 | "orl %"_LO32 _tmp",%"_sav"; " | ||
332 | |||
333 | #ifdef CONFIG_X86_64 | 293 | #ifdef CONFIG_X86_64 |
334 | #define ON64(x) x | 294 | #define ON64(x) x |
335 | #else | 295 | #else |
336 | #define ON64(x) | 296 | #define ON64(x) |
337 | #endif | 297 | #endif |
338 | 298 | ||
339 | #define ____emulate_2op(ctxt, _op, _x, _y, _suffix, _dsttype) \ | ||
340 | do { \ | ||
341 | __asm__ __volatile__ ( \ | ||
342 | _PRE_EFLAGS("0", "4", "2") \ | ||
343 | _op _suffix " %"_x"3,%1; " \ | ||
344 | _POST_EFLAGS("0", "4", "2") \ | ||
345 | : "=m" ((ctxt)->eflags), \ | ||
346 | "+q" (*(_dsttype*)&(ctxt)->dst.val), \ | ||
347 | "=&r" (_tmp) \ | ||
348 | : _y ((ctxt)->src.val), "i" (EFLAGS_MASK)); \ | ||
349 | } while (0) | ||
350 | |||
351 | |||
352 | /* Raw emulation: instruction has two explicit operands. */ | ||
353 | #define __emulate_2op_nobyte(ctxt,_op,_wx,_wy,_lx,_ly,_qx,_qy) \ | ||
354 | do { \ | ||
355 | unsigned long _tmp; \ | ||
356 | \ | ||
357 | switch ((ctxt)->dst.bytes) { \ | ||
358 | case 2: \ | ||
359 | ____emulate_2op(ctxt,_op,_wx,_wy,"w",u16); \ | ||
360 | break; \ | ||
361 | case 4: \ | ||
362 | ____emulate_2op(ctxt,_op,_lx,_ly,"l",u32); \ | ||
363 | break; \ | ||
364 | case 8: \ | ||
365 | ON64(____emulate_2op(ctxt,_op,_qx,_qy,"q",u64)); \ | ||
366 | break; \ | ||
367 | } \ | ||
368 | } while (0) | ||
369 | |||
370 | #define __emulate_2op(ctxt,_op,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ | ||
371 | do { \ | ||
372 | unsigned long _tmp; \ | ||
373 | switch ((ctxt)->dst.bytes) { \ | ||
374 | case 1: \ | ||
375 | ____emulate_2op(ctxt,_op,_bx,_by,"b",u8); \ | ||
376 | break; \ | ||
377 | default: \ | ||
378 | __emulate_2op_nobyte(ctxt, _op, \ | ||
379 | _wx, _wy, _lx, _ly, _qx, _qy); \ | ||
380 | break; \ | ||
381 | } \ | ||
382 | } while (0) | ||
383 | |||
384 | /* Source operand is byte-sized and may be restricted to just %cl. */ | ||
385 | #define emulate_2op_SrcB(ctxt, _op) \ | ||
386 | __emulate_2op(ctxt, _op, "b", "c", "b", "c", "b", "c", "b", "c") | ||
387 | |||
388 | /* Source operand is byte, word, long or quad sized. */ | ||
389 | #define emulate_2op_SrcV(ctxt, _op) \ | ||
390 | __emulate_2op(ctxt, _op, "b", "q", "w", "r", _LO32, "r", "", "r") | ||
391 | |||
392 | /* Source operand is word, long or quad sized. */ | ||
393 | #define emulate_2op_SrcV_nobyte(ctxt, _op) \ | ||
394 | __emulate_2op_nobyte(ctxt, _op, "w", "r", _LO32, "r", "", "r") | ||
395 | |||
396 | /* Instruction has three operands and one operand is stored in ECX register */ | ||
397 | #define __emulate_2op_cl(ctxt, _op, _suffix, _type) \ | ||
398 | do { \ | ||
399 | unsigned long _tmp; \ | ||
400 | _type _clv = (ctxt)->src2.val; \ | ||
401 | _type _srcv = (ctxt)->src.val; \ | ||
402 | _type _dstv = (ctxt)->dst.val; \ | ||
403 | \ | ||
404 | __asm__ __volatile__ ( \ | ||
405 | _PRE_EFLAGS("0", "5", "2") \ | ||
406 | _op _suffix " %4,%1 \n" \ | ||
407 | _POST_EFLAGS("0", "5", "2") \ | ||
408 | : "=m" ((ctxt)->eflags), "+r" (_dstv), "=&r" (_tmp) \ | ||
409 | : "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK) \ | ||
410 | ); \ | ||
411 | \ | ||
412 | (ctxt)->src2.val = (unsigned long) _clv; \ | ||
413 | (ctxt)->src2.val = (unsigned long) _srcv; \ | ||
414 | (ctxt)->dst.val = (unsigned long) _dstv; \ | ||
415 | } while (0) | ||
416 | |||
417 | #define emulate_2op_cl(ctxt, _op) \ | ||
418 | do { \ | ||
419 | switch ((ctxt)->dst.bytes) { \ | ||
420 | case 2: \ | ||
421 | __emulate_2op_cl(ctxt, _op, "w", u16); \ | ||
422 | break; \ | ||
423 | case 4: \ | ||
424 | __emulate_2op_cl(ctxt, _op, "l", u32); \ | ||
425 | break; \ | ||
426 | case 8: \ | ||
427 | ON64(__emulate_2op_cl(ctxt, _op, "q", ulong)); \ | ||
428 | break; \ | ||
429 | } \ | ||
430 | } while (0) | ||
431 | |||
432 | #define __emulate_1op(ctxt, _op, _suffix) \ | ||
433 | do { \ | ||
434 | unsigned long _tmp; \ | ||
435 | \ | ||
436 | __asm__ __volatile__ ( \ | ||
437 | _PRE_EFLAGS("0", "3", "2") \ | ||
438 | _op _suffix " %1; " \ | ||
439 | _POST_EFLAGS("0", "3", "2") \ | ||
440 | : "=m" ((ctxt)->eflags), "+m" ((ctxt)->dst.val), \ | ||
441 | "=&r" (_tmp) \ | ||
442 | : "i" (EFLAGS_MASK)); \ | ||
443 | } while (0) | ||
444 | |||
445 | /* Instruction has only one explicit operand (no source operand). */ | ||
446 | #define emulate_1op(ctxt, _op) \ | ||
447 | do { \ | ||
448 | switch ((ctxt)->dst.bytes) { \ | ||
449 | case 1: __emulate_1op(ctxt, _op, "b"); break; \ | ||
450 | case 2: __emulate_1op(ctxt, _op, "w"); break; \ | ||
451 | case 4: __emulate_1op(ctxt, _op, "l"); break; \ | ||
452 | case 8: ON64(__emulate_1op(ctxt, _op, "q")); break; \ | ||
453 | } \ | ||
454 | } while (0) | ||
455 | |||
456 | 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 *)); |
457 | 300 | ||
458 | #define FOP_ALIGN ".align " __stringify(FASTOP_SIZE) " \n\t" | 301 | #define FOP_ALIGN ".align " __stringify(FASTOP_SIZE) " \n\t" |
@@ -571,47 +414,6 @@ FOP_END; | |||
571 | 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 |
572 | FOP_END; | 415 | FOP_END; |
573 | 416 | ||
574 | #define __emulate_1op_rax_rdx(ctxt, _op, _suffix, _ex) \ | ||
575 | do { \ | ||
576 | unsigned long _tmp; \ | ||
577 | ulong *rax = &ctxt->dst.val; \ | ||
578 | ulong *rdx = &ctxt->src.val; \ | ||
579 | \ | ||
580 | __asm__ __volatile__ ( \ | ||
581 | _PRE_EFLAGS("0", "5", "1") \ | ||
582 | "1: \n\t" \ | ||
583 | _op _suffix " %6; " \ | ||
584 | "2: \n\t" \ | ||
585 | _POST_EFLAGS("0", "5", "1") \ | ||
586 | ".pushsection .fixup,\"ax\" \n\t" \ | ||
587 | "3: movb $1, %4 \n\t" \ | ||
588 | "jmp 2b \n\t" \ | ||
589 | ".popsection \n\t" \ | ||
590 | _ASM_EXTABLE(1b, 3b) \ | ||
591 | : "=m" ((ctxt)->eflags), "=&r" (_tmp), \ | ||
592 | "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \ | ||
593 | : "i" (EFLAGS_MASK), "m" ((ctxt)->src2.val)); \ | ||
594 | } while (0) | ||
595 | |||
596 | /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ | ||
597 | #define emulate_1op_rax_rdx(ctxt, _op, _ex) \ | ||
598 | do { \ | ||
599 | switch((ctxt)->src.bytes) { \ | ||
600 | case 1: \ | ||
601 | __emulate_1op_rax_rdx(ctxt, _op, "b", _ex); \ | ||
602 | break; \ | ||
603 | case 2: \ | ||
604 | __emulate_1op_rax_rdx(ctxt, _op, "w", _ex); \ | ||
605 | break; \ | ||
606 | case 4: \ | ||
607 | __emulate_1op_rax_rdx(ctxt, _op, "l", _ex); \ | ||
608 | break; \ | ||
609 | case 8: ON64( \ | ||
610 | __emulate_1op_rax_rdx(ctxt, _op, "q", _ex)); \ | ||
611 | break; \ | ||
612 | } \ | ||
613 | } while (0) | ||
614 | |||
615 | static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt, | 417 | static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt, |
616 | enum x86_intercept intercept, | 418 | enum x86_intercept intercept, |
617 | enum x86_intercept_stage stage) | 419 | enum x86_intercept_stage stage) |