diff options
author | Laurent Vivier <Laurent.Vivier@bull.net> | 2007-09-18 05:52:50 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:52:47 -0500 |
commit | e4e03deda83b1f2fc37ccbfc1eef27e86e8ed4e9 (patch) | |
tree | 5306b8f262bddcc4e5a59520f8628d85a5b4eaf7 /drivers/kvm/x86_emulate.c | |
parent | a7ddce3afc8326870b9e5e02fa41e028bffb10a5 (diff) |
KVM: x86 emulator: move all x86_emulate_memop() to a structure
Move all x86_emulate_memop() common variables between decode and execute to a
structure decode_cache. This will help in later separating decode and
emulate.
struct decode_cache {
u8 twobyte;
u8 b;
u8 lock_prefix;
u8 rep_prefix;
u8 op_bytes;
u8 ad_bytes;
struct operand src;
struct operand dst;
unsigned long *override_base;
unsigned int d;
unsigned long regs[NR_VCPU_REGS];
unsigned long eip;
/* modrm */
u8 modrm;
u8 modrm_mod;
u8 modrm_reg;
u8 modrm_rm;
u8 use_modrm_ea;
unsigned long modrm_ea;
unsigned long modrm_val;
};
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/x86_emulate.c')
-rw-r--r-- | drivers/kvm/x86_emulate.c | 919 |
1 files changed, 484 insertions, 435 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index 9ea82f84743e..d7026cb8fc70 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
@@ -222,13 +222,6 @@ static u16 twobyte_table[256] = { | |||
222 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | 222 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
223 | }; | 223 | }; |
224 | 224 | ||
225 | /* Type, address-of, and value of an instruction's operand. */ | ||
226 | struct operand { | ||
227 | enum { OP_REG, OP_MEM, OP_IMM } type; | ||
228 | unsigned int bytes; | ||
229 | unsigned long val, orig_val, *ptr; | ||
230 | }; | ||
231 | |||
232 | /* EFLAGS bit definitions. */ | 225 | /* EFLAGS bit definitions. */ |
233 | #define EFLG_OF (1<<11) | 226 | #define EFLG_OF (1<<11) |
234 | #define EFLG_DF (1<<10) | 227 | #define EFLG_DF (1<<10) |
@@ -431,24 +424,26 @@ struct operand { | |||
431 | 424 | ||
432 | /* Access/update address held in a register, based on addressing mode. */ | 425 | /* Access/update address held in a register, based on addressing mode. */ |
433 | #define address_mask(reg) \ | 426 | #define address_mask(reg) \ |
434 | ((ad_bytes == sizeof(unsigned long)) ? \ | 427 | ((c->ad_bytes == sizeof(unsigned long)) ? \ |
435 | (reg) : ((reg) & ((1UL << (ad_bytes << 3)) - 1))) | 428 | (reg) : ((reg) & ((1UL << (c->ad_bytes << 3)) - 1))) |
436 | #define register_address(base, reg) \ | 429 | #define register_address(base, reg) \ |
437 | ((base) + address_mask(reg)) | 430 | ((base) + address_mask(reg)) |
438 | #define register_address_increment(reg, inc) \ | 431 | #define register_address_increment(reg, inc) \ |
439 | do { \ | 432 | do { \ |
440 | /* signed type ensures sign extension to long */ \ | 433 | /* signed type ensures sign extension to long */ \ |
441 | int _inc = (inc); \ | 434 | int _inc = (inc); \ |
442 | if ( ad_bytes == sizeof(unsigned long) ) \ | 435 | if (c->ad_bytes == sizeof(unsigned long)) \ |
443 | (reg) += _inc; \ | 436 | (reg) += _inc; \ |
444 | else \ | 437 | else \ |
445 | (reg) = ((reg) & ~((1UL << (ad_bytes << 3)) - 1)) | \ | 438 | (reg) = ((reg) & \ |
446 | (((reg) + _inc) & ((1UL << (ad_bytes << 3)) - 1)); \ | 439 | ~((1UL << (c->ad_bytes << 3)) - 1)) | \ |
440 | (((reg) + _inc) & \ | ||
441 | ((1UL << (c->ad_bytes << 3)) - 1)); \ | ||
447 | } while (0) | 442 | } while (0) |
448 | 443 | ||
449 | #define JMP_REL(rel) \ | 444 | #define JMP_REL(rel) \ |
450 | do { \ | 445 | do { \ |
451 | register_address_increment(_eip, rel); \ | 446 | register_address_increment(c->eip, rel); \ |
452 | } while (0) | 447 | } while (0) |
453 | 448 | ||
454 | /* | 449 | /* |
@@ -524,39 +519,35 @@ static int test_cc(unsigned int condition, unsigned int flags) | |||
524 | int | 519 | int |
525 | x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | 520 | x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) |
526 | { | 521 | { |
527 | unsigned d; | 522 | struct decode_cache *c = &ctxt->decode; |
528 | u8 b, sib, twobyte = 0, rex_prefix = 0; | 523 | u8 sib, rex_prefix = 0; |
529 | u8 modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; | 524 | unsigned int i; |
530 | unsigned long *override_base = NULL; | ||
531 | unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; | ||
532 | int rc = 0; | 525 | int rc = 0; |
533 | struct operand src, dst; | ||
534 | unsigned long cr2 = ctxt->cr2; | 526 | unsigned long cr2 = ctxt->cr2; |
535 | int mode = ctxt->mode; | 527 | int mode = ctxt->mode; |
536 | unsigned long modrm_ea; | 528 | int index_reg = 0, base_reg = 0, scale, rip_relative = 0; |
537 | int use_modrm_ea, index_reg = 0, base_reg = 0, scale, rip_relative = 0; | ||
538 | int no_wb = 0; | 529 | int no_wb = 0; |
539 | u64 msr_data; | 530 | u64 msr_data; |
540 | 531 | ||
541 | /* Shadow copy of register state. Committed on successful emulation. */ | 532 | /* Shadow copy of register state. Committed on successful emulation. */ |
542 | unsigned long _regs[NR_VCPU_REGS]; | 533 | unsigned long _eflags = ctxt->eflags; |
543 | unsigned long _eip = ctxt->vcpu->rip, _eflags = ctxt->eflags; | ||
544 | unsigned long modrm_val = 0; | ||
545 | 534 | ||
546 | memcpy(_regs, ctxt->vcpu->regs, sizeof _regs); | 535 | memset(c, 0, sizeof(struct decode_cache)); |
536 | c->eip = ctxt->vcpu->rip; | ||
537 | memcpy(c->regs, ctxt->vcpu->regs, sizeof c->regs); | ||
547 | 538 | ||
548 | switch (mode) { | 539 | switch (mode) { |
549 | case X86EMUL_MODE_REAL: | 540 | case X86EMUL_MODE_REAL: |
550 | case X86EMUL_MODE_PROT16: | 541 | case X86EMUL_MODE_PROT16: |
551 | op_bytes = ad_bytes = 2; | 542 | c->op_bytes = c->ad_bytes = 2; |
552 | break; | 543 | break; |
553 | case X86EMUL_MODE_PROT32: | 544 | case X86EMUL_MODE_PROT32: |
554 | op_bytes = ad_bytes = 4; | 545 | c->op_bytes = c->ad_bytes = 4; |
555 | break; | 546 | break; |
556 | #ifdef CONFIG_X86_64 | 547 | #ifdef CONFIG_X86_64 |
557 | case X86EMUL_MODE_PROT64: | 548 | case X86EMUL_MODE_PROT64: |
558 | op_bytes = 4; | 549 | c->op_bytes = 4; |
559 | ad_bytes = 8; | 550 | c->ad_bytes = 8; |
560 | break; | 551 | break; |
561 | #endif | 552 | #endif |
562 | default: | 553 | default: |
@@ -565,40 +556,42 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
565 | 556 | ||
566 | /* Legacy prefixes. */ | 557 | /* Legacy prefixes. */ |
567 | for (i = 0; i < 8; i++) { | 558 | for (i = 0; i < 8; i++) { |
568 | switch (b = insn_fetch(u8, 1, _eip)) { | 559 | switch (c->b = insn_fetch(u8, 1, c->eip)) { |
569 | case 0x66: /* operand-size override */ | 560 | case 0x66: /* operand-size override */ |
570 | op_bytes ^= 6; /* switch between 2/4 bytes */ | 561 | c->op_bytes ^= 6; /* switch between 2/4 bytes */ |
571 | break; | 562 | break; |
572 | case 0x67: /* address-size override */ | 563 | case 0x67: /* address-size override */ |
573 | if (mode == X86EMUL_MODE_PROT64) | 564 | if (mode == X86EMUL_MODE_PROT64) |
574 | ad_bytes ^= 12; /* switch between 4/8 bytes */ | 565 | /* switch between 4/8 bytes */ |
566 | c->ad_bytes ^= 12; | ||
575 | else | 567 | else |
576 | ad_bytes ^= 6; /* switch between 2/4 bytes */ | 568 | /* switch between 2/4 bytes */ |
569 | c->ad_bytes ^= 6; | ||
577 | break; | 570 | break; |
578 | case 0x2e: /* CS override */ | 571 | case 0x2e: /* CS override */ |
579 | override_base = &ctxt->cs_base; | 572 | c->override_base = &ctxt->cs_base; |
580 | break; | 573 | break; |
581 | case 0x3e: /* DS override */ | 574 | case 0x3e: /* DS override */ |
582 | override_base = &ctxt->ds_base; | 575 | c->override_base = &ctxt->ds_base; |
583 | break; | 576 | break; |
584 | case 0x26: /* ES override */ | 577 | case 0x26: /* ES override */ |
585 | override_base = &ctxt->es_base; | 578 | c->override_base = &ctxt->es_base; |
586 | break; | 579 | break; |
587 | case 0x64: /* FS override */ | 580 | case 0x64: /* FS override */ |
588 | override_base = &ctxt->fs_base; | 581 | c->override_base = &ctxt->fs_base; |
589 | break; | 582 | break; |
590 | case 0x65: /* GS override */ | 583 | case 0x65: /* GS override */ |
591 | override_base = &ctxt->gs_base; | 584 | c->override_base = &ctxt->gs_base; |
592 | break; | 585 | break; |
593 | case 0x36: /* SS override */ | 586 | case 0x36: /* SS override */ |
594 | override_base = &ctxt->ss_base; | 587 | c->override_base = &ctxt->ss_base; |
595 | break; | 588 | break; |
596 | case 0xf0: /* LOCK */ | 589 | case 0xf0: /* LOCK */ |
597 | lock_prefix = 1; | 590 | c->lock_prefix = 1; |
598 | break; | 591 | break; |
599 | case 0xf2: /* REPNE/REPNZ */ | 592 | case 0xf2: /* REPNE/REPNZ */ |
600 | case 0xf3: /* REP/REPE/REPZ */ | 593 | case 0xf3: /* REP/REPE/REPZ */ |
601 | rep_prefix = 1; | 594 | c->rep_prefix = 1; |
602 | break; | 595 | break; |
603 | default: | 596 | default: |
604 | goto done_prefixes; | 597 | goto done_prefixes; |
@@ -608,177 +601,182 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | |||
608 | done_prefixes: | 601 | done_prefixes: |
609 | 602 | ||
610 | /* REX prefix. */ | 603 | /* REX prefix. */ |
611 | if ((mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40)) { | 604 | if ((mode == X86EMUL_MODE_PROT64) && ((c->b & 0xf0) == 0x40)) { |
612 | rex_prefix = b; | 605 | rex_prefix = c->b; |
613 | if (b & 8) | 606 | if (c->b & 8) |
614 | op_bytes = 8; /* REX.W */ | 607 | c->op_bytes = 8; /* REX.W */ |
615 | modrm_reg = (b & 4) << 1; /* REX.R */ | 608 | c->modrm_reg = (c->b & 4) << 1; /* REX.R */ |
616 | index_reg = (b & 2) << 2; /* REX.X */ | 609 | index_reg = (c->b & 2) << 2; /* REX.X */ |
617 | modrm_rm = base_reg = (b & 1) << 3; /* REG.B */ | 610 | c->modrm_rm = base_reg = (c->b & 1) << 3; /* REG.B */ |
618 | b = insn_fetch(u8, 1, _eip); | 611 | c->b = insn_fetch(u8, 1, c->eip); |
619 | } | 612 | } |
620 | 613 | ||
621 | /* Opcode byte(s). */ | 614 | /* Opcode byte(s). */ |
622 | d = opcode_table[b]; | 615 | c->d = opcode_table[c->b]; |
623 | if (d == 0) { | 616 | if (c->d == 0) { |
624 | /* Two-byte opcode? */ | 617 | /* Two-byte opcode? */ |
625 | if (b == 0x0f) { | 618 | if (c->b == 0x0f) { |
626 | twobyte = 1; | 619 | c->twobyte = 1; |
627 | b = insn_fetch(u8, 1, _eip); | 620 | c->b = insn_fetch(u8, 1, c->eip); |
628 | d = twobyte_table[b]; | 621 | c->d = twobyte_table[c->b]; |
629 | } | 622 | } |
630 | 623 | ||
631 | /* Unrecognised? */ | 624 | /* Unrecognised? */ |
632 | if (d == 0) | 625 | if (c->d == 0) |
633 | goto cannot_emulate; | 626 | goto cannot_emulate; |
634 | } | 627 | } |
635 | 628 | ||
636 | /* ModRM and SIB bytes. */ | 629 | /* ModRM and SIB bytes. */ |
637 | if (d & ModRM) { | 630 | if (c->d & ModRM) { |
638 | modrm = insn_fetch(u8, 1, _eip); | 631 | c->modrm = insn_fetch(u8, 1, c->eip); |
639 | modrm_mod |= (modrm & 0xc0) >> 6; | 632 | c->modrm_mod |= (c->modrm & 0xc0) >> 6; |
640 | modrm_reg |= (modrm & 0x38) >> 3; | 633 | c->modrm_reg |= (c->modrm & 0x38) >> 3; |
641 | modrm_rm |= (modrm & 0x07); | 634 | c->modrm_rm |= (c->modrm & 0x07); |
642 | modrm_ea = 0; | 635 | c->modrm_ea = 0; |
643 | use_modrm_ea = 1; | 636 | c->use_modrm_ea = 1; |
644 | 637 | ||
645 | if (modrm_mod == 3) { | 638 | if (c->modrm_mod == 3) { |
646 | modrm_val = *(unsigned long *) | 639 | c->modrm_val = *(unsigned long *) |
647 | decode_register(modrm_rm, _regs, d & ByteOp); | 640 | decode_register(c->modrm_rm, c->regs, c->d & ByteOp); |
648 | goto modrm_done; | 641 | goto modrm_done; |
649 | } | 642 | } |
650 | 643 | ||
651 | if (ad_bytes == 2) { | 644 | if (c->ad_bytes == 2) { |
652 | unsigned bx = _regs[VCPU_REGS_RBX]; | 645 | unsigned bx = c->regs[VCPU_REGS_RBX]; |
653 | unsigned bp = _regs[VCPU_REGS_RBP]; | 646 | unsigned bp = c->regs[VCPU_REGS_RBP]; |
654 | unsigned si = _regs[VCPU_REGS_RSI]; | 647 | unsigned si = c->regs[VCPU_REGS_RSI]; |
655 | unsigned di = _regs[VCPU_REGS_RDI]; | 648 | unsigned di = c->regs[VCPU_REGS_RDI]; |
656 | 649 | ||
657 | /* 16-bit ModR/M decode. */ | 650 | /* 16-bit ModR/M decode. */ |
658 | switch (modrm_mod) { | 651 | switch (c->modrm_mod) { |
659 | case 0: | 652 | case 0: |
660 | if (modrm_rm == 6) | 653 | if (c->modrm_rm == 6) |
661 | modrm_ea += insn_fetch(u16, 2, _eip); | 654 | c->modrm_ea += |
655 | insn_fetch(u16, 2, c->eip); | ||
662 | break; | 656 | break; |
663 | case 1: | 657 | case 1: |
664 | modrm_ea += insn_fetch(s8, 1, _eip); | 658 | c->modrm_ea += insn_fetch(s8, 1, c->eip); |
665 | break; | 659 | break; |
666 | case 2: | 660 | case 2: |
667 | modrm_ea += insn_fetch(u16, 2, _eip); | 661 | c->modrm_ea += insn_fetch(u16, 2, c->eip); |
668 | break; | 662 | break; |
669 | } | 663 | } |
670 | switch (modrm_rm) { | 664 | switch (c->modrm_rm) { |
671 | case 0: | 665 | case 0: |
672 | modrm_ea += bx + si; | 666 | c->modrm_ea += bx + si; |
673 | break; | 667 | break; |
674 | case 1: | 668 | case 1: |
675 | modrm_ea += bx + di; | 669 | c->modrm_ea += bx + di; |
676 | break; | 670 | break; |
677 | case 2: | 671 | case 2: |
678 | modrm_ea += bp + si; | 672 | c->modrm_ea += bp + si; |
679 | break; | 673 | break; |
680 | case 3: | 674 | case 3: |
681 | modrm_ea += bp + di; | 675 | c->modrm_ea += bp + di; |
682 | break; | 676 | break; |
683 | case 4: | 677 | case 4: |
684 | modrm_ea += si; | 678 | c->modrm_ea += si; |
685 | break; | 679 | break; |
686 | case 5: | 680 | case 5: |
687 | modrm_ea += di; | 681 | c->modrm_ea += di; |
688 | break; | 682 | break; |
689 | case 6: | 683 | case 6: |
690 | if (modrm_mod != 0) | 684 | if (c->modrm_mod != 0) |
691 | modrm_ea += bp; | 685 | c->modrm_ea += bp; |
692 | break; | 686 | break; |
693 | case 7: | 687 | case 7: |
694 | modrm_ea += bx; | 688 | c->modrm_ea += bx; |
695 | break; | 689 | break; |
696 | } | 690 | } |
697 | if (modrm_rm == 2 || modrm_rm == 3 || | 691 | if (c->modrm_rm == 2 || c->modrm_rm == 3 || |
698 | (modrm_rm == 6 && modrm_mod != 0)) | 692 | (c->modrm_rm == 6 && c->modrm_mod != 0)) |
699 | if (!override_base) | 693 | if (!c->override_base) |
700 | override_base = &ctxt->ss_base; | 694 | c->override_base = &ctxt->ss_base; |
701 | modrm_ea = (u16)modrm_ea; | 695 | c->modrm_ea = (u16)c->modrm_ea; |
702 | } else { | 696 | } else { |
703 | /* 32/64-bit ModR/M decode. */ | 697 | /* 32/64-bit ModR/M decode. */ |
704 | switch (modrm_rm) { | 698 | switch (c->modrm_rm) { |
705 | case 4: | 699 | case 4: |
706 | case 12: | 700 | case 12: |
707 | sib = insn_fetch(u8, 1, _eip); | 701 | sib = insn_fetch(u8, 1, c->eip); |
708 | index_reg |= (sib >> 3) & 7; | 702 | index_reg |= (sib >> 3) & 7; |
709 | base_reg |= sib & 7; | 703 | base_reg |= sib & 7; |
710 | scale = sib >> 6; | 704 | scale = sib >> 6; |
711 | 705 | ||
712 | switch (base_reg) { | 706 | switch (base_reg) { |
713 | case 5: | 707 | case 5: |
714 | if (modrm_mod != 0) | 708 | if (c->modrm_mod != 0) |
715 | modrm_ea += _regs[base_reg]; | 709 | c->modrm_ea += |
710 | c->regs[base_reg]; | ||
716 | else | 711 | else |
717 | modrm_ea += insn_fetch(s32, 4, _eip); | 712 | c->modrm_ea += |
713 | insn_fetch(s32, 4, c->eip); | ||
718 | break; | 714 | break; |
719 | default: | 715 | default: |
720 | modrm_ea += _regs[base_reg]; | 716 | c->modrm_ea += c->regs[base_reg]; |
721 | } | 717 | } |
722 | switch (index_reg) { | 718 | switch (index_reg) { |
723 | case 4: | 719 | case 4: |
724 | break; | 720 | break; |
725 | default: | 721 | default: |
726 | modrm_ea += _regs[index_reg] << scale; | 722 | c->modrm_ea += |
723 | c->regs[index_reg] << scale; | ||
727 | 724 | ||
728 | } | 725 | } |
729 | break; | 726 | break; |
730 | case 5: | 727 | case 5: |
731 | if (modrm_mod != 0) | 728 | if (c->modrm_mod != 0) |
732 | modrm_ea += _regs[modrm_rm]; | 729 | c->modrm_ea += c->regs[c->modrm_rm]; |
733 | else if (mode == X86EMUL_MODE_PROT64) | 730 | else if (mode == X86EMUL_MODE_PROT64) |
734 | rip_relative = 1; | 731 | rip_relative = 1; |
735 | break; | 732 | break; |
736 | default: | 733 | default: |
737 | modrm_ea += _regs[modrm_rm]; | 734 | c->modrm_ea += c->regs[c->modrm_rm]; |
738 | break; | 735 | break; |
739 | } | 736 | } |
740 | switch (modrm_mod) { | 737 | switch (c->modrm_mod) { |
741 | case 0: | 738 | case 0: |
742 | if (modrm_rm == 5) | 739 | if (c->modrm_rm == 5) |
743 | modrm_ea += insn_fetch(s32, 4, _eip); | 740 | c->modrm_ea += |
741 | insn_fetch(s32, 4, c->eip); | ||
744 | break; | 742 | break; |
745 | case 1: | 743 | case 1: |
746 | modrm_ea += insn_fetch(s8, 1, _eip); | 744 | c->modrm_ea += insn_fetch(s8, 1, c->eip); |
747 | break; | 745 | break; |
748 | case 2: | 746 | case 2: |
749 | modrm_ea += insn_fetch(s32, 4, _eip); | 747 | c->modrm_ea += insn_fetch(s32, 4, c->eip); |
750 | break; | 748 | break; |
751 | } | 749 | } |
752 | } | 750 | } |
753 | if (!override_base) | 751 | if (!c->override_base) |
754 | override_base = &ctxt->ds_base; | 752 | c->override_base = &ctxt->ds_base; |
755 | if (mode == X86EMUL_MODE_PROT64 && | 753 | if (mode == X86EMUL_MODE_PROT64 && |
756 | override_base != &ctxt->fs_base && | 754 | c->override_base != &ctxt->fs_base && |
757 | override_base != &ctxt->gs_base) | 755 | c->override_base != &ctxt->gs_base) |
758 | override_base = NULL; | 756 | c->override_base = NULL; |
759 | 757 | ||
760 | if (override_base) | 758 | if (c->override_base) |
761 | modrm_ea += *override_base; | 759 | c->modrm_ea += *c->override_base; |
762 | 760 | ||
763 | if (rip_relative) { | 761 | if (rip_relative) { |
764 | modrm_ea += _eip; | 762 | c->modrm_ea += c->eip; |
765 | switch (d & SrcMask) { | 763 | switch (c->d & SrcMask) { |
766 | case SrcImmByte: | 764 | case SrcImmByte: |
767 | modrm_ea += 1; | 765 | c->modrm_ea += 1; |
768 | break; | 766 | break; |
769 | case SrcImm: | 767 | case SrcImm: |
770 | if (d & ByteOp) | 768 | if (c->d & ByteOp) |
771 | modrm_ea += 1; | 769 | c->modrm_ea += 1; |
772 | else | 770 | else |
773 | if (op_bytes == 8) | 771 | if (c->op_bytes == 8) |
774 | modrm_ea += 4; | 772 | c->modrm_ea += 4; |
775 | else | 773 | else |
776 | modrm_ea += op_bytes; | 774 | c->modrm_ea += c->op_bytes; |
777 | } | 775 | } |
778 | } | 776 | } |
779 | if (ad_bytes != 8) | 777 | if (c->ad_bytes != 8) |
780 | modrm_ea = (u32)modrm_ea; | 778 | c->modrm_ea = (u32)c->modrm_ea; |
781 | cr2 = modrm_ea; | 779 | cr2 = c->modrm_ea; |
782 | modrm_done: | 780 | modrm_done: |
783 | ; | 781 | ; |
784 | } | 782 | } |
@@ -787,200 +785,210 @@ done_prefixes: | |||
787 | * Decode and fetch the source operand: register, memory | 785 | * Decode and fetch the source operand: register, memory |
788 | * or immediate. | 786 | * or immediate. |
789 | */ | 787 | */ |
790 | switch (d & SrcMask) { | 788 | switch (c->d & SrcMask) { |
791 | case SrcNone: | 789 | case SrcNone: |
792 | break; | 790 | break; |
793 | case SrcReg: | 791 | case SrcReg: |
794 | src.type = OP_REG; | 792 | c->src.type = OP_REG; |
795 | if (d & ByteOp) { | 793 | if (c->d & ByteOp) { |
796 | src.ptr = decode_register(modrm_reg, _regs, | 794 | c->src.ptr = |
795 | decode_register(c->modrm_reg, c->regs, | ||
797 | (rex_prefix == 0)); | 796 | (rex_prefix == 0)); |
798 | src.val = src.orig_val = *(u8 *) src.ptr; | 797 | c->src.val = c->src.orig_val = *(u8 *)c->src.ptr; |
799 | src.bytes = 1; | 798 | c->src.bytes = 1; |
800 | } else { | 799 | } else { |
801 | src.ptr = decode_register(modrm_reg, _regs, 0); | 800 | c->src.ptr = |
802 | switch ((src.bytes = op_bytes)) { | 801 | decode_register(c->modrm_reg, c->regs, 0); |
802 | switch ((c->src.bytes = c->op_bytes)) { | ||
803 | case 2: | 803 | case 2: |
804 | src.val = src.orig_val = *(u16 *) src.ptr; | 804 | c->src.val = c->src.orig_val = |
805 | *(u16 *) c->src.ptr; | ||
805 | break; | 806 | break; |
806 | case 4: | 807 | case 4: |
807 | src.val = src.orig_val = *(u32 *) src.ptr; | 808 | c->src.val = c->src.orig_val = |
809 | *(u32 *) c->src.ptr; | ||
808 | break; | 810 | break; |
809 | case 8: | 811 | case 8: |
810 | src.val = src.orig_val = *(u64 *) src.ptr; | 812 | c->src.val = c->src.orig_val = |
813 | *(u64 *) c->src.ptr; | ||
811 | break; | 814 | break; |
812 | } | 815 | } |
813 | } | 816 | } |
814 | break; | 817 | break; |
815 | case SrcMem16: | 818 | case SrcMem16: |
816 | src.bytes = 2; | 819 | c->src.bytes = 2; |
817 | goto srcmem_common; | 820 | goto srcmem_common; |
818 | case SrcMem32: | 821 | case SrcMem32: |
819 | src.bytes = 4; | 822 | c->src.bytes = 4; |
820 | goto srcmem_common; | 823 | goto srcmem_common; |
821 | case SrcMem: | 824 | case SrcMem: |
822 | src.bytes = (d & ByteOp) ? 1 : op_bytes; | 825 | c->src.bytes = (c->d & ByteOp) ? 1 : |
826 | c->op_bytes; | ||
823 | /* Don't fetch the address for invlpg: it could be unmapped. */ | 827 | /* Don't fetch the address for invlpg: it could be unmapped. */ |
824 | if (twobyte && b == 0x01 && modrm_reg == 7) | 828 | if (c->twobyte && c->b == 0x01 |
829 | && c->modrm_reg == 7) | ||
825 | break; | 830 | break; |
826 | srcmem_common: | 831 | srcmem_common: |
827 | /* | 832 | /* |
828 | * For instructions with a ModR/M byte, switch to register | 833 | * For instructions with a ModR/M byte, switch to register |
829 | * access if Mod = 3. | 834 | * access if Mod = 3. |
830 | */ | 835 | */ |
831 | if ((d & ModRM) && modrm_mod == 3) { | 836 | if ((c->d & ModRM) && c->modrm_mod == 3) { |
832 | src.type = OP_REG; | 837 | c->src.type = OP_REG; |
833 | break; | 838 | break; |
834 | } | 839 | } |
835 | src.type = OP_MEM; | 840 | c->src.type = OP_MEM; |
836 | src.ptr = (unsigned long *)cr2; | 841 | c->src.ptr = (unsigned long *)cr2; |
837 | src.val = 0; | 842 | c->src.val = 0; |
838 | if ((rc = ops->read_emulated((unsigned long)src.ptr, | 843 | if ((rc = ops->read_emulated((unsigned long)c->src.ptr, |
839 | &src.val, src.bytes, ctxt->vcpu)) != 0) | 844 | &c->src.val, |
845 | c->src.bytes, ctxt->vcpu)) != 0) | ||
840 | goto done; | 846 | goto done; |
841 | src.orig_val = src.val; | 847 | c->src.orig_val = c->src.val; |
842 | break; | 848 | break; |
843 | case SrcImm: | 849 | case SrcImm: |
844 | src.type = OP_IMM; | 850 | c->src.type = OP_IMM; |
845 | src.ptr = (unsigned long *)_eip; | 851 | c->src.ptr = (unsigned long *)c->eip; |
846 | src.bytes = (d & ByteOp) ? 1 : op_bytes; | 852 | c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
847 | if (src.bytes == 8) | 853 | if (c->src.bytes == 8) |
848 | src.bytes = 4; | 854 | c->src.bytes = 4; |
849 | /* NB. Immediates are sign-extended as necessary. */ | 855 | /* NB. Immediates are sign-extended as necessary. */ |
850 | switch (src.bytes) { | 856 | switch (c->src.bytes) { |
851 | case 1: | 857 | case 1: |
852 | src.val = insn_fetch(s8, 1, _eip); | 858 | c->src.val = insn_fetch(s8, 1, c->eip); |
853 | break; | 859 | break; |
854 | case 2: | 860 | case 2: |
855 | src.val = insn_fetch(s16, 2, _eip); | 861 | c->src.val = insn_fetch(s16, 2, c->eip); |
856 | break; | 862 | break; |
857 | case 4: | 863 | case 4: |
858 | src.val = insn_fetch(s32, 4, _eip); | 864 | c->src.val = insn_fetch(s32, 4, c->eip); |
859 | break; | 865 | break; |
860 | } | 866 | } |
861 | break; | 867 | break; |
862 | case SrcImmByte: | 868 | case SrcImmByte: |
863 | src.type = OP_IMM; | 869 | c->src.type = OP_IMM; |
864 | src.ptr = (unsigned long *)_eip; | 870 | c->src.ptr = (unsigned long *)c->eip; |
865 | src.bytes = 1; | 871 | c->src.bytes = 1; |
866 | src.val = insn_fetch(s8, 1, _eip); | 872 | c->src.val = insn_fetch(s8, 1, c->eip); |
867 | break; | 873 | break; |
868 | } | 874 | } |
869 | 875 | ||
870 | /* Decode and fetch the destination operand: register or memory. */ | 876 | /* Decode and fetch the destination operand: register or memory. */ |
871 | switch (d & DstMask) { | 877 | switch (c->d & DstMask) { |
872 | case ImplicitOps: | 878 | case ImplicitOps: |
873 | /* Special instructions do their own operand decoding. */ | 879 | /* Special instructions do their own operand decoding. */ |
874 | goto special_insn; | 880 | goto special_insn; |
875 | case DstReg: | 881 | case DstReg: |
876 | dst.type = OP_REG; | 882 | c->dst.type = OP_REG; |
877 | if ((d & ByteOp) | 883 | if ((c->d & ByteOp) |
878 | && !(twobyte && (b == 0xb6 || b == 0xb7))) { | 884 | && !(c->twobyte && |
879 | dst.ptr = decode_register(modrm_reg, _regs, | 885 | (c->b == 0xb6 || c->b == 0xb7))) { |
886 | c->dst.ptr = | ||
887 | decode_register(c->modrm_reg, c->regs, | ||
880 | (rex_prefix == 0)); | 888 | (rex_prefix == 0)); |
881 | dst.val = *(u8 *) dst.ptr; | 889 | c->dst.val = *(u8 *) c->dst.ptr; |
882 | dst.bytes = 1; | 890 | c->dst.bytes = 1; |
883 | } else { | 891 | } else { |
884 | dst.ptr = decode_register(modrm_reg, _regs, 0); | 892 | c->dst.ptr = |
885 | switch ((dst.bytes = op_bytes)) { | 893 | decode_register(c->modrm_reg, c->regs, 0); |
894 | switch ((c->dst.bytes = c->op_bytes)) { | ||
886 | case 2: | 895 | case 2: |
887 | dst.val = *(u16 *)dst.ptr; | 896 | c->dst.val = *(u16 *)c->dst.ptr; |
888 | break; | 897 | break; |
889 | case 4: | 898 | case 4: |
890 | dst.val = *(u32 *)dst.ptr; | 899 | c->dst.val = *(u32 *)c->dst.ptr; |
891 | break; | 900 | break; |
892 | case 8: | 901 | case 8: |
893 | dst.val = *(u64 *)dst.ptr; | 902 | c->dst.val = *(u64 *)c->dst.ptr; |
894 | break; | 903 | break; |
895 | } | 904 | } |
896 | } | 905 | } |
897 | break; | 906 | break; |
898 | case DstMem: | 907 | case DstMem: |
899 | dst.type = OP_MEM; | 908 | c->dst.type = OP_MEM; |
900 | dst.ptr = (unsigned long *)cr2; | 909 | c->dst.ptr = (unsigned long *)cr2; |
901 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; | 910 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
902 | dst.val = 0; | 911 | c->dst.val = 0; |
903 | /* | 912 | if ((c->d & ModRM) && c->modrm_mod == 3) { |
904 | * For instructions with a ModR/M byte, switch to register | 913 | c->dst.type = OP_REG; |
905 | * access if Mod = 3. | ||
906 | */ | ||
907 | if ((d & ModRM) && modrm_mod == 3) { | ||
908 | dst.type = OP_REG; | ||
909 | break; | 914 | break; |
910 | } | 915 | } |
911 | if (d & BitOp) { | 916 | if (c->d & BitOp) { |
912 | unsigned long mask = ~(dst.bytes * 8 - 1); | 917 | unsigned long mask = ~(c->dst.bytes * 8 - 1); |
913 | 918 | ||
914 | dst.ptr = (void *)dst.ptr + (src.val & mask) / 8; | 919 | c->dst.ptr = (void *)c->dst.ptr + |
920 | (c->src.val & mask) / 8; | ||
915 | } | 921 | } |
916 | if (!(d & Mov) && /* optimisation - avoid slow emulated read */ | 922 | if (!(c->d & Mov) && |
917 | ((rc = ops->read_emulated((unsigned long)dst.ptr, | 923 | /* optimisation - avoid slow emulated read */ |
918 | &dst.val, dst.bytes, ctxt->vcpu)) != 0)) | 924 | ((rc = ops->read_emulated((unsigned long)c->dst.ptr, |
925 | &c->dst.val, | ||
926 | c->dst.bytes, ctxt->vcpu)) != 0)) | ||
919 | goto done; | 927 | goto done; |
920 | break; | 928 | break; |
921 | } | 929 | } |
922 | dst.orig_val = dst.val; | 930 | c->dst.orig_val = c->dst.val; |
923 | 931 | ||
924 | if (twobyte) | 932 | if (c->twobyte) |
925 | goto twobyte_insn; | 933 | goto twobyte_insn; |
926 | 934 | ||
927 | switch (b) { | 935 | switch (c->b) { |
928 | case 0x00 ... 0x05: | 936 | case 0x00 ... 0x05: |
929 | add: /* add */ | 937 | add: /* add */ |
930 | emulate_2op_SrcV("add", src, dst, _eflags); | 938 | emulate_2op_SrcV("add", c->src, c->dst, _eflags); |
931 | break; | 939 | break; |
932 | case 0x08 ... 0x0d: | 940 | case 0x08 ... 0x0d: |
933 | or: /* or */ | 941 | or: /* or */ |
934 | emulate_2op_SrcV("or", src, dst, _eflags); | 942 | emulate_2op_SrcV("or", c->src, c->dst, _eflags); |
935 | break; | 943 | break; |
936 | case 0x10 ... 0x15: | 944 | case 0x10 ... 0x15: |
937 | adc: /* adc */ | 945 | adc: /* adc */ |
938 | emulate_2op_SrcV("adc", src, dst, _eflags); | 946 | emulate_2op_SrcV("adc", c->src, c->dst, _eflags); |
939 | break; | 947 | break; |
940 | case 0x18 ... 0x1d: | 948 | case 0x18 ... 0x1d: |
941 | sbb: /* sbb */ | 949 | sbb: /* sbb */ |
942 | emulate_2op_SrcV("sbb", src, dst, _eflags); | 950 | emulate_2op_SrcV("sbb", c->src, c->dst, _eflags); |
943 | break; | 951 | break; |
944 | case 0x20 ... 0x23: | 952 | case 0x20 ... 0x23: |
945 | and: /* and */ | 953 | and: /* and */ |
946 | emulate_2op_SrcV("and", src, dst, _eflags); | 954 | emulate_2op_SrcV("and", c->src, c->dst, _eflags); |
947 | break; | 955 | break; |
948 | case 0x24: /* and al imm8 */ | 956 | case 0x24: /* and al imm8 */ |
949 | dst.type = OP_REG; | 957 | c->dst.type = OP_REG; |
950 | dst.ptr = &_regs[VCPU_REGS_RAX]; | 958 | c->dst.ptr = &c->regs[VCPU_REGS_RAX]; |
951 | dst.val = *(u8 *)dst.ptr; | 959 | c->dst.val = *(u8 *)c->dst.ptr; |
952 | dst.bytes = 1; | 960 | c->dst.bytes = 1; |
953 | dst.orig_val = dst.val; | 961 | c->dst.orig_val = c->dst.val; |
954 | goto and; | 962 | goto and; |
955 | case 0x25: /* and ax imm16, or eax imm32 */ | 963 | case 0x25: /* and ax imm16, or eax imm32 */ |
956 | dst.type = OP_REG; | 964 | c->dst.type = OP_REG; |
957 | dst.bytes = op_bytes; | 965 | c->dst.bytes = c->op_bytes; |
958 | dst.ptr = &_regs[VCPU_REGS_RAX]; | 966 | c->dst.ptr = &c->regs[VCPU_REGS_RAX]; |
959 | if (op_bytes == 2) | 967 | if (c->op_bytes == 2) |
960 | dst.val = *(u16 *)dst.ptr; | 968 | c->dst.val = *(u16 *)c->dst.ptr; |
961 | else | 969 | else |
962 | dst.val = *(u32 *)dst.ptr; | 970 | c->dst.val = *(u32 *)c->dst.ptr; |
963 | dst.orig_val = dst.val; | 971 | c->dst.orig_val = c->dst.val; |
964 | goto and; | 972 | goto and; |
965 | case 0x28 ... 0x2d: | 973 | case 0x28 ... 0x2d: |
966 | sub: /* sub */ | 974 | sub: /* sub */ |
967 | emulate_2op_SrcV("sub", src, dst, _eflags); | 975 | emulate_2op_SrcV("sub", c->src, c->dst, _eflags); |
968 | break; | 976 | break; |
969 | case 0x30 ... 0x35: | 977 | case 0x30 ... 0x35: |
970 | xor: /* xor */ | 978 | xor: /* xor */ |
971 | emulate_2op_SrcV("xor", src, dst, _eflags); | 979 | emulate_2op_SrcV("xor", c->src, c->dst, _eflags); |
972 | break; | 980 | break; |
973 | case 0x38 ... 0x3d: | 981 | case 0x38 ... 0x3d: |
974 | cmp: /* cmp */ | 982 | cmp: /* cmp */ |
975 | emulate_2op_SrcV("cmp", src, dst, _eflags); | 983 | emulate_2op_SrcV("cmp", c->src, c->dst, _eflags); |
976 | break; | 984 | break; |
977 | case 0x63: /* movsxd */ | 985 | case 0x63: /* movsxd */ |
978 | if (mode != X86EMUL_MODE_PROT64) | 986 | if (mode != X86EMUL_MODE_PROT64) |
979 | goto cannot_emulate; | 987 | goto cannot_emulate; |
980 | dst.val = (s32) src.val; | 988 | c->dst.val = (s32) c->src.val; |
981 | break; | 989 | break; |
982 | case 0x80 ... 0x83: /* Grp1 */ | 990 | case 0x80 ... 0x83: /* Grp1 */ |
983 | switch (modrm_reg) { | 991 | switch (c->modrm_reg) { |
984 | case 0: | 992 | case 0: |
985 | goto add; | 993 | goto add; |
986 | case 1: | 994 | case 1: |
@@ -1001,155 +1009,164 @@ done_prefixes: | |||
1001 | break; | 1009 | break; |
1002 | case 0x84 ... 0x85: | 1010 | case 0x84 ... 0x85: |
1003 | test: /* test */ | 1011 | test: /* test */ |
1004 | emulate_2op_SrcV("test", src, dst, _eflags); | 1012 | emulate_2op_SrcV("test", c->src, c->dst, _eflags); |
1005 | break; | 1013 | break; |
1006 | case 0x86 ... 0x87: /* xchg */ | 1014 | case 0x86 ... 0x87: /* xchg */ |
1007 | /* Write back the register source. */ | 1015 | /* Write back the register source. */ |
1008 | switch (dst.bytes) { | 1016 | switch (c->dst.bytes) { |
1009 | case 1: | 1017 | case 1: |
1010 | *(u8 *) src.ptr = (u8) dst.val; | 1018 | *(u8 *) c->src.ptr = (u8) c->dst.val; |
1011 | break; | 1019 | break; |
1012 | case 2: | 1020 | case 2: |
1013 | *(u16 *) src.ptr = (u16) dst.val; | 1021 | *(u16 *) c->src.ptr = (u16) c->dst.val; |
1014 | break; | 1022 | break; |
1015 | case 4: | 1023 | case 4: |
1016 | *src.ptr = (u32) dst.val; | 1024 | *c->src.ptr = (u32) c->dst.val; |
1017 | break; /* 64b reg: zero-extend */ | 1025 | break; /* 64b reg: zero-extend */ |
1018 | case 8: | 1026 | case 8: |
1019 | *src.ptr = dst.val; | 1027 | *c->src.ptr = c->dst.val; |
1020 | break; | 1028 | break; |
1021 | } | 1029 | } |
1022 | /* | 1030 | /* |
1023 | * Write back the memory destination with implicit LOCK | 1031 | * Write back the memory destination with implicit LOCK |
1024 | * prefix. | 1032 | * prefix. |
1025 | */ | 1033 | */ |
1026 | dst.val = src.val; | 1034 | c->dst.val = c->src.val; |
1027 | lock_prefix = 1; | 1035 | c->lock_prefix = 1; |
1028 | break; | 1036 | break; |
1029 | case 0x88 ... 0x8b: /* mov */ | 1037 | case 0x88 ... 0x8b: /* mov */ |
1030 | goto mov; | 1038 | goto mov; |
1031 | case 0x8d: /* lea r16/r32, m */ | 1039 | case 0x8d: /* lea r16/r32, m */ |
1032 | dst.val = modrm_val; | 1040 | c->dst.val = c->modrm_val; |
1033 | break; | 1041 | break; |
1034 | case 0x8f: /* pop (sole member of Grp1a) */ | 1042 | case 0x8f: /* pop (sole member of Grp1a) */ |
1035 | /* 64-bit mode: POP always pops a 64-bit operand. */ | 1043 | /* 64-bit mode: POP always pops a 64-bit operand. */ |
1036 | if (mode == X86EMUL_MODE_PROT64) | 1044 | if (mode == X86EMUL_MODE_PROT64) |
1037 | dst.bytes = 8; | 1045 | c->dst.bytes = 8; |
1038 | if ((rc = ops->read_std(register_address(ctxt->ss_base, | 1046 | if ((rc = ops->read_std(register_address( |
1039 | _regs[VCPU_REGS_RSP]), | 1047 | ctxt->ss_base, |
1040 | &dst.val, dst.bytes, ctxt->vcpu)) != 0) | 1048 | c->regs[VCPU_REGS_RSP]), |
1049 | &c->dst.val, | ||
1050 | c->dst.bytes, | ||
1051 | ctxt->vcpu)) != 0) | ||
1041 | goto done; | 1052 | goto done; |
1042 | register_address_increment(_regs[VCPU_REGS_RSP], dst.bytes); | 1053 | register_address_increment(c->regs[VCPU_REGS_RSP], |
1054 | c->dst.bytes); | ||
1043 | break; | 1055 | break; |
1044 | case 0xa0 ... 0xa1: /* mov */ | 1056 | case 0xa0 ... 0xa1: /* mov */ |
1045 | dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX]; | 1057 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; |
1046 | dst.val = src.val; | 1058 | c->dst.val = c->src.val; |
1047 | _eip += ad_bytes; /* skip src displacement */ | 1059 | /* skip src displacement */ |
1060 | c->eip += c->ad_bytes; | ||
1048 | break; | 1061 | break; |
1049 | case 0xa2 ... 0xa3: /* mov */ | 1062 | case 0xa2 ... 0xa3: /* mov */ |
1050 | dst.val = (unsigned long)_regs[VCPU_REGS_RAX]; | 1063 | c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX]; |
1051 | _eip += ad_bytes; /* skip dst displacement */ | 1064 | /* skip c->dst displacement */ |
1065 | c->eip += c->ad_bytes; | ||
1052 | break; | 1066 | break; |
1053 | case 0xc0 ... 0xc1: | 1067 | case 0xc0 ... 0xc1: |
1054 | grp2: /* Grp2 */ | 1068 | grp2: /* Grp2 */ |
1055 | switch (modrm_reg) { | 1069 | switch (c->modrm_reg) { |
1056 | case 0: /* rol */ | 1070 | case 0: /* rol */ |
1057 | emulate_2op_SrcB("rol", src, dst, _eflags); | 1071 | emulate_2op_SrcB("rol", c->src, c->dst, _eflags); |
1058 | break; | 1072 | break; |
1059 | case 1: /* ror */ | 1073 | case 1: /* ror */ |
1060 | emulate_2op_SrcB("ror", src, dst, _eflags); | 1074 | emulate_2op_SrcB("ror", c->src, c->dst, _eflags); |
1061 | break; | 1075 | break; |
1062 | case 2: /* rcl */ | 1076 | case 2: /* rcl */ |
1063 | emulate_2op_SrcB("rcl", src, dst, _eflags); | 1077 | emulate_2op_SrcB("rcl", c->src, c->dst, _eflags); |
1064 | break; | 1078 | break; |
1065 | case 3: /* rcr */ | 1079 | case 3: /* rcr */ |
1066 | emulate_2op_SrcB("rcr", src, dst, _eflags); | 1080 | emulate_2op_SrcB("rcr", c->src, c->dst, _eflags); |
1067 | break; | 1081 | break; |
1068 | case 4: /* sal/shl */ | 1082 | case 4: /* sal/shl */ |
1069 | case 6: /* sal/shl */ | 1083 | case 6: /* sal/shl */ |
1070 | emulate_2op_SrcB("sal", src, dst, _eflags); | 1084 | emulate_2op_SrcB("sal", c->src, c->dst, _eflags); |
1071 | break; | 1085 | break; |
1072 | case 5: /* shr */ | 1086 | case 5: /* shr */ |
1073 | emulate_2op_SrcB("shr", src, dst, _eflags); | 1087 | emulate_2op_SrcB("shr", c->src, c->dst, _eflags); |
1074 | break; | 1088 | break; |
1075 | case 7: /* sar */ | 1089 | case 7: /* sar */ |
1076 | emulate_2op_SrcB("sar", src, dst, _eflags); | 1090 | emulate_2op_SrcB("sar", c->src, c->dst, _eflags); |
1077 | break; | 1091 | break; |
1078 | } | 1092 | } |
1079 | break; | 1093 | break; |
1080 | case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ | 1094 | case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ |
1081 | mov: | 1095 | mov: |
1082 | dst.val = src.val; | 1096 | c->dst.val = c->src.val; |
1083 | break; | 1097 | break; |
1084 | case 0xd0 ... 0xd1: /* Grp2 */ | 1098 | case 0xd0 ... 0xd1: /* Grp2 */ |
1085 | src.val = 1; | 1099 | c->src.val = 1; |
1086 | goto grp2; | 1100 | goto grp2; |
1087 | case 0xd2 ... 0xd3: /* Grp2 */ | 1101 | case 0xd2 ... 0xd3: /* Grp2 */ |
1088 | src.val = _regs[VCPU_REGS_RCX]; | 1102 | c->src.val = c->regs[VCPU_REGS_RCX]; |
1089 | goto grp2; | 1103 | goto grp2; |
1090 | case 0xf6 ... 0xf7: /* Grp3 */ | 1104 | case 0xf6 ... 0xf7: /* Grp3 */ |
1091 | switch (modrm_reg) { | 1105 | switch (c->modrm_reg) { |
1092 | case 0 ... 1: /* test */ | 1106 | case 0 ... 1: /* test */ |
1093 | /* | 1107 | /* |
1094 | * Special case in Grp3: test has an immediate | 1108 | * Special case in Grp3: test has an immediate |
1095 | * source operand. | 1109 | * source operand. |
1096 | */ | 1110 | */ |
1097 | src.type = OP_IMM; | 1111 | c->src.type = OP_IMM; |
1098 | src.ptr = (unsigned long *)_eip; | 1112 | c->src.ptr = (unsigned long *)c->eip; |
1099 | src.bytes = (d & ByteOp) ? 1 : op_bytes; | 1113 | c->src.bytes = (c->d & ByteOp) ? 1 : |
1100 | if (src.bytes == 8) | 1114 | c->op_bytes; |
1101 | src.bytes = 4; | 1115 | if (c->src.bytes == 8) |
1102 | switch (src.bytes) { | 1116 | c->src.bytes = 4; |
1117 | switch (c->src.bytes) { | ||
1103 | case 1: | 1118 | case 1: |
1104 | src.val = insn_fetch(s8, 1, _eip); | 1119 | c->src.val = insn_fetch(s8, 1, c->eip); |
1105 | break; | 1120 | break; |
1106 | case 2: | 1121 | case 2: |
1107 | src.val = insn_fetch(s16, 2, _eip); | 1122 | c->src.val = insn_fetch(s16, 2, c->eip); |
1108 | break; | 1123 | break; |
1109 | case 4: | 1124 | case 4: |
1110 | src.val = insn_fetch(s32, 4, _eip); | 1125 | c->src.val = insn_fetch(s32, 4, c->eip); |
1111 | break; | 1126 | break; |
1112 | } | 1127 | } |
1113 | goto test; | 1128 | goto test; |
1114 | case 2: /* not */ | 1129 | case 2: /* not */ |
1115 | dst.val = ~dst.val; | 1130 | c->dst.val = ~c->dst.val; |
1116 | break; | 1131 | break; |
1117 | case 3: /* neg */ | 1132 | case 3: /* neg */ |
1118 | emulate_1op("neg", dst, _eflags); | 1133 | emulate_1op("neg", c->dst, _eflags); |
1119 | break; | 1134 | break; |
1120 | default: | 1135 | default: |
1121 | goto cannot_emulate; | 1136 | goto cannot_emulate; |
1122 | } | 1137 | } |
1123 | break; | 1138 | break; |
1124 | case 0xfe ... 0xff: /* Grp4/Grp5 */ | 1139 | case 0xfe ... 0xff: /* Grp4/Grp5 */ |
1125 | switch (modrm_reg) { | 1140 | switch (c->modrm_reg) { |
1126 | case 0: /* inc */ | 1141 | case 0: /* inc */ |
1127 | emulate_1op("inc", dst, _eflags); | 1142 | emulate_1op("inc", c->dst, _eflags); |
1128 | break; | 1143 | break; |
1129 | case 1: /* dec */ | 1144 | case 1: /* dec */ |
1130 | emulate_1op("dec", dst, _eflags); | 1145 | emulate_1op("dec", c->dst, _eflags); |
1131 | break; | 1146 | break; |
1132 | case 4: /* jmp abs */ | 1147 | case 4: /* jmp abs */ |
1133 | if (b == 0xff) | 1148 | if (c->b == 0xff) |
1134 | _eip = dst.val; | 1149 | c->eip = c->dst.val; |
1135 | else | 1150 | else |
1136 | goto cannot_emulate; | 1151 | goto cannot_emulate; |
1137 | break; | 1152 | break; |
1138 | case 6: /* push */ | 1153 | case 6: /* push */ |
1139 | /* 64-bit mode: PUSH always pushes a 64-bit operand. */ | 1154 | /* 64-bit mode: PUSH always pushes a 64-bit operand. */ |
1140 | if (mode == X86EMUL_MODE_PROT64) { | 1155 | if (mode == X86EMUL_MODE_PROT64) { |
1141 | dst.bytes = 8; | 1156 | c->dst.bytes = 8; |
1142 | if ((rc = ops->read_std((unsigned long)dst.ptr, | 1157 | if ((rc = ops->read_std( |
1143 | &dst.val, 8, | 1158 | (unsigned long)c->dst.ptr, |
1144 | ctxt->vcpu)) != 0) | 1159 | &c->dst.val, 8, |
1160 | ctxt->vcpu)) != 0) | ||
1145 | goto done; | 1161 | goto done; |
1146 | } | 1162 | } |
1147 | register_address_increment(_regs[VCPU_REGS_RSP], | 1163 | register_address_increment(c->regs[VCPU_REGS_RSP], |
1148 | -dst.bytes); | 1164 | -c->dst.bytes); |
1149 | if ((rc = ops->write_emulated( | 1165 | if ((rc = ops->write_emulated( |
1150 | register_address(ctxt->ss_base, | 1166 | register_address(ctxt->ss_base, |
1151 | _regs[VCPU_REGS_RSP]), | 1167 | c->regs[VCPU_REGS_RSP]), |
1152 | &dst.val, dst.bytes, ctxt->vcpu)) != 0) | 1168 | &c->dst.val, |
1169 | c->dst.bytes, ctxt->vcpu)) != 0) | ||
1153 | goto done; | 1170 | goto done; |
1154 | no_wb = 1; | 1171 | no_wb = 1; |
1155 | break; | 1172 | break; |
@@ -1161,34 +1178,40 @@ done_prefixes: | |||
1161 | 1178 | ||
1162 | writeback: | 1179 | writeback: |
1163 | if (!no_wb) { | 1180 | if (!no_wb) { |
1164 | switch (dst.type) { | 1181 | switch (c->dst.type) { |
1165 | case OP_REG: | 1182 | case OP_REG: |
1166 | /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ | 1183 | /* The 4-byte case *is* correct: |
1167 | switch (dst.bytes) { | 1184 | * in 64-bit mode we zero-extend. |
1185 | */ | ||
1186 | switch (c->dst.bytes) { | ||
1168 | case 1: | 1187 | case 1: |
1169 | *(u8 *)dst.ptr = (u8)dst.val; | 1188 | *(u8 *)c->dst.ptr = (u8)c->dst.val; |
1170 | break; | 1189 | break; |
1171 | case 2: | 1190 | case 2: |
1172 | *(u16 *)dst.ptr = (u16)dst.val; | 1191 | *(u16 *)c->dst.ptr = (u16)c->dst.val; |
1173 | break; | 1192 | break; |
1174 | case 4: | 1193 | case 4: |
1175 | *dst.ptr = (u32)dst.val; | 1194 | *c->dst.ptr = (u32)c->dst.val; |
1176 | break; /* 64b: zero-ext */ | 1195 | break; /* 64b: zero-ext */ |
1177 | case 8: | 1196 | case 8: |
1178 | *dst.ptr = dst.val; | 1197 | *c->dst.ptr = c->dst.val; |
1179 | break; | 1198 | break; |
1180 | } | 1199 | } |
1181 | break; | 1200 | break; |
1182 | case OP_MEM: | 1201 | case OP_MEM: |
1183 | if (lock_prefix) | 1202 | if (c->lock_prefix) |
1184 | rc = ops->cmpxchg_emulated((unsigned long)dst. | 1203 | rc = ops->cmpxchg_emulated( |
1185 | ptr, &dst.orig_val, | 1204 | (unsigned long)c->dst.ptr, |
1186 | &dst.val, dst.bytes, | 1205 | &c->dst.orig_val, |
1187 | ctxt->vcpu); | 1206 | &c->dst.val, |
1207 | c->dst.bytes, | ||
1208 | ctxt->vcpu); | ||
1188 | else | 1209 | else |
1189 | rc = ops->write_emulated((unsigned long)dst.ptr, | 1210 | rc = ops->write_emulated( |
1190 | &dst.val, dst.bytes, | 1211 | (unsigned long)c->dst.ptr, |
1191 | ctxt->vcpu); | 1212 | &c->dst.val, |
1213 | c->dst.bytes, | ||
1214 | ctxt->vcpu); | ||
1192 | if (rc != 0) | 1215 | if (rc != 0) |
1193 | goto done; | 1216 | goto done; |
1194 | default: | 1217 | default: |
@@ -1197,173 +1220,185 @@ writeback: | |||
1197 | } | 1220 | } |
1198 | 1221 | ||
1199 | /* Commit shadow register state. */ | 1222 | /* Commit shadow register state. */ |
1200 | memcpy(ctxt->vcpu->regs, _regs, sizeof _regs); | 1223 | memcpy(ctxt->vcpu->regs, c->regs, sizeof c->regs); |
1201 | ctxt->eflags = _eflags; | 1224 | ctxt->eflags = _eflags; |
1202 | ctxt->vcpu->rip = _eip; | 1225 | ctxt->vcpu->rip = c->eip; |
1203 | 1226 | ||
1204 | done: | 1227 | done: |
1205 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; | 1228 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; |
1206 | 1229 | ||
1207 | special_insn: | 1230 | special_insn: |
1208 | if (twobyte) | 1231 | if (c->twobyte) |
1209 | goto twobyte_special_insn; | 1232 | goto twobyte_special_insn; |
1210 | switch(b) { | 1233 | switch (c->b) { |
1211 | case 0x50 ... 0x57: /* push reg */ | 1234 | case 0x50 ... 0x57: /* push reg */ |
1212 | if (op_bytes == 2) | 1235 | if (c->op_bytes == 2) |
1213 | src.val = (u16) _regs[b & 0x7]; | 1236 | c->src.val = (u16) c->regs[c->b & 0x7]; |
1214 | else | 1237 | else |
1215 | src.val = (u32) _regs[b & 0x7]; | 1238 | c->src.val = (u32) c->regs[c->b & 0x7]; |
1216 | dst.type = OP_MEM; | 1239 | c->dst.type = OP_MEM; |
1217 | dst.bytes = op_bytes; | 1240 | c->dst.bytes = c->op_bytes; |
1218 | dst.val = src.val; | 1241 | c->dst.val = c->src.val; |
1219 | register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes); | 1242 | register_address_increment(c->regs[VCPU_REGS_RSP], |
1220 | dst.ptr = (void *) register_address( | 1243 | -c->op_bytes); |
1221 | ctxt->ss_base, _regs[VCPU_REGS_RSP]); | 1244 | c->dst.ptr = (void *) register_address( |
1245 | ctxt->ss_base, c->regs[VCPU_REGS_RSP]); | ||
1222 | break; | 1246 | break; |
1223 | case 0x58 ... 0x5f: /* pop reg */ | 1247 | case 0x58 ... 0x5f: /* pop reg */ |
1224 | dst.ptr = (unsigned long *)&_regs[b & 0x7]; | 1248 | c->dst.ptr = |
1249 | (unsigned long *)&c->regs[c->b & 0x7]; | ||
1225 | pop_instruction: | 1250 | pop_instruction: |
1226 | if ((rc = ops->read_std(register_address(ctxt->ss_base, | 1251 | if ((rc = ops->read_std(register_address(ctxt->ss_base, |
1227 | _regs[VCPU_REGS_RSP]), dst.ptr, op_bytes, ctxt->vcpu)) | 1252 | c->regs[VCPU_REGS_RSP]), c->dst.ptr, |
1228 | != 0) | 1253 | c->op_bytes, ctxt->vcpu)) != 0) |
1229 | goto done; | 1254 | goto done; |
1230 | 1255 | ||
1231 | register_address_increment(_regs[VCPU_REGS_RSP], op_bytes); | 1256 | register_address_increment(c->regs[VCPU_REGS_RSP], |
1257 | c->op_bytes); | ||
1232 | no_wb = 1; /* Disable writeback. */ | 1258 | no_wb = 1; /* Disable writeback. */ |
1233 | break; | 1259 | break; |
1234 | case 0x6a: /* push imm8 */ | 1260 | case 0x6a: /* push imm8 */ |
1235 | src.val = 0L; | 1261 | c->src.val = 0L; |
1236 | src.val = insn_fetch(s8, 1, _eip); | 1262 | c->src.val = insn_fetch(s8, 1, c->eip); |
1237 | push: | 1263 | push: |
1238 | dst.type = OP_MEM; | 1264 | c->dst.type = OP_MEM; |
1239 | dst.bytes = op_bytes; | 1265 | c->dst.bytes = c->op_bytes; |
1240 | dst.val = src.val; | 1266 | c->dst.val = c->src.val; |
1241 | register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes); | 1267 | register_address_increment(c->regs[VCPU_REGS_RSP], |
1242 | dst.ptr = (void *) register_address(ctxt->ss_base, | 1268 | -c->op_bytes); |
1243 | _regs[VCPU_REGS_RSP]); | 1269 | c->dst.ptr = (void *) register_address(ctxt->ss_base, |
1270 | c->regs[VCPU_REGS_RSP]); | ||
1244 | break; | 1271 | break; |
1245 | case 0x6c: /* insb */ | 1272 | case 0x6c: /* insb */ |
1246 | case 0x6d: /* insw/insd */ | 1273 | case 0x6d: /* insw/insd */ |
1247 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, | 1274 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, |
1248 | 1, /* in */ | 1275 | 1, |
1249 | (d & ByteOp) ? 1 : op_bytes, /* size */ | 1276 | (c->d & ByteOp) ? 1 : c->op_bytes, |
1250 | rep_prefix ? | 1277 | c->rep_prefix ? |
1251 | address_mask(_regs[VCPU_REGS_RCX]) : 1, /* count */ | 1278 | address_mask(c->regs[VCPU_REGS_RCX]) : 1, |
1252 | (_eflags & EFLG_DF), /* down */ | 1279 | (_eflags & EFLG_DF), |
1253 | register_address(ctxt->es_base, | 1280 | register_address(ctxt->es_base, |
1254 | _regs[VCPU_REGS_RDI]), /* address */ | 1281 | c->regs[VCPU_REGS_RDI]), |
1255 | rep_prefix, | 1282 | c->rep_prefix, |
1256 | _regs[VCPU_REGS_RDX] /* port */ | 1283 | c->regs[VCPU_REGS_RDX]) == 0) |
1257 | ) == 0) | ||
1258 | return -1; | 1284 | return -1; |
1259 | return 0; | 1285 | return 0; |
1260 | case 0x6e: /* outsb */ | 1286 | case 0x6e: /* outsb */ |
1261 | case 0x6f: /* outsw/outsd */ | 1287 | case 0x6f: /* outsw/outsd */ |
1262 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, | 1288 | if (kvm_emulate_pio_string(ctxt->vcpu, NULL, |
1263 | 0, /* in */ | 1289 | 0, |
1264 | (d & ByteOp) ? 1 : op_bytes, /* size */ | 1290 | (c->d & ByteOp) ? 1 : c->op_bytes, |
1265 | rep_prefix ? | 1291 | c->rep_prefix ? |
1266 | address_mask(_regs[VCPU_REGS_RCX]) : 1, /* count */ | 1292 | address_mask(c->regs[VCPU_REGS_RCX]) : 1, |
1267 | (_eflags & EFLG_DF), /* down */ | 1293 | (_eflags & EFLG_DF), |
1268 | register_address(override_base ? | 1294 | register_address(c->override_base ? |
1269 | *override_base : ctxt->ds_base, | 1295 | *c->override_base : |
1270 | _regs[VCPU_REGS_RSI]), /* address */ | 1296 | ctxt->ds_base, |
1271 | rep_prefix, | 1297 | c->regs[VCPU_REGS_RSI]), |
1272 | _regs[VCPU_REGS_RDX] /* port */ | 1298 | c->rep_prefix, |
1273 | ) == 0) | 1299 | c->regs[VCPU_REGS_RDX]) == 0) |
1274 | return -1; | 1300 | return -1; |
1275 | return 0; | 1301 | return 0; |
1276 | case 0x70 ... 0x7f: /* jcc (short) */ { | 1302 | case 0x70 ... 0x7f: /* jcc (short) */ { |
1277 | int rel = insn_fetch(s8, 1, _eip); | 1303 | int rel = insn_fetch(s8, 1, c->eip); |
1278 | 1304 | ||
1279 | if (test_cc(b, _eflags)) | 1305 | if (test_cc(c->b, _eflags)) |
1280 | JMP_REL(rel); | 1306 | JMP_REL(rel); |
1281 | break; | 1307 | break; |
1282 | } | 1308 | } |
1283 | case 0x9c: /* pushf */ | 1309 | case 0x9c: /* pushf */ |
1284 | src.val = (unsigned long) _eflags; | 1310 | c->src.val = (unsigned long) _eflags; |
1285 | goto push; | 1311 | goto push; |
1286 | case 0x9d: /* popf */ | 1312 | case 0x9d: /* popf */ |
1287 | dst.ptr = (unsigned long *) &_eflags; | 1313 | c->dst.ptr = (unsigned long *) &_eflags; |
1288 | goto pop_instruction; | 1314 | goto pop_instruction; |
1289 | case 0xc3: /* ret */ | 1315 | case 0xc3: /* ret */ |
1290 | dst.ptr = &_eip; | 1316 | c->dst.ptr = &c->eip; |
1291 | goto pop_instruction; | 1317 | goto pop_instruction; |
1292 | case 0xf4: /* hlt */ | 1318 | case 0xf4: /* hlt */ |
1293 | ctxt->vcpu->halt_request = 1; | 1319 | ctxt->vcpu->halt_request = 1; |
1294 | goto done; | 1320 | goto done; |
1295 | } | 1321 | } |
1296 | if (rep_prefix) { | 1322 | if (c->rep_prefix) { |
1297 | if (_regs[VCPU_REGS_RCX] == 0) { | 1323 | if (c->regs[VCPU_REGS_RCX] == 0) { |
1298 | ctxt->vcpu->rip = _eip; | 1324 | ctxt->vcpu->rip = c->eip; |
1299 | goto done; | 1325 | goto done; |
1300 | } | 1326 | } |
1301 | _regs[VCPU_REGS_RCX]--; | 1327 | c->regs[VCPU_REGS_RCX]--; |
1302 | _eip = ctxt->vcpu->rip; | 1328 | c->eip = ctxt->vcpu->rip; |
1303 | } | 1329 | } |
1304 | switch (b) { | 1330 | switch (c->b) { |
1305 | case 0xa4 ... 0xa5: /* movs */ | 1331 | case 0xa4 ... 0xa5: /* movs */ |
1306 | dst.type = OP_MEM; | 1332 | c->dst.type = OP_MEM; |
1307 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; | 1333 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
1308 | dst.ptr = (unsigned long *)register_address(ctxt->es_base, | 1334 | c->dst.ptr = (unsigned long *)register_address( |
1309 | _regs[VCPU_REGS_RDI]); | 1335 | ctxt->es_base, |
1336 | c->regs[VCPU_REGS_RDI]); | ||
1310 | if ((rc = ops->read_emulated(register_address( | 1337 | if ((rc = ops->read_emulated(register_address( |
1311 | override_base ? *override_base : ctxt->ds_base, | 1338 | c->override_base ? *c->override_base : |
1312 | _regs[VCPU_REGS_RSI]), &dst.val, dst.bytes, ctxt->vcpu)) != 0) | 1339 | ctxt->ds_base, |
1340 | c->regs[VCPU_REGS_RSI]), | ||
1341 | &c->dst.val, | ||
1342 | c->dst.bytes, ctxt->vcpu)) != 0) | ||
1313 | goto done; | 1343 | goto done; |
1314 | register_address_increment(_regs[VCPU_REGS_RSI], | 1344 | register_address_increment(c->regs[VCPU_REGS_RSI], |
1315 | (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes); | 1345 | (_eflags & EFLG_DF) ? -c->dst.bytes |
1316 | register_address_increment(_regs[VCPU_REGS_RDI], | 1346 | : c->dst.bytes); |
1317 | (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes); | 1347 | register_address_increment(c->regs[VCPU_REGS_RDI], |
1348 | (_eflags & EFLG_DF) ? -c->dst.bytes | ||
1349 | : c->dst.bytes); | ||
1318 | break; | 1350 | break; |
1319 | case 0xa6 ... 0xa7: /* cmps */ | 1351 | case 0xa6 ... 0xa7: /* cmps */ |
1320 | DPRINTF("Urk! I don't handle CMPS.\n"); | 1352 | DPRINTF("Urk! I don't handle CMPS.\n"); |
1321 | goto cannot_emulate; | 1353 | goto cannot_emulate; |
1322 | case 0xaa ... 0xab: /* stos */ | 1354 | case 0xaa ... 0xab: /* stos */ |
1323 | dst.type = OP_MEM; | 1355 | c->dst.type = OP_MEM; |
1324 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; | 1356 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
1325 | dst.ptr = (unsigned long *)cr2; | 1357 | c->dst.ptr = (unsigned long *)cr2; |
1326 | dst.val = _regs[VCPU_REGS_RAX]; | 1358 | c->dst.val = c->regs[VCPU_REGS_RAX]; |
1327 | register_address_increment(_regs[VCPU_REGS_RDI], | 1359 | register_address_increment(c->regs[VCPU_REGS_RDI], |
1328 | (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes); | 1360 | (_eflags & EFLG_DF) ? -c->dst.bytes |
1361 | : c->dst.bytes); | ||
1329 | break; | 1362 | break; |
1330 | case 0xac ... 0xad: /* lods */ | 1363 | case 0xac ... 0xad: /* lods */ |
1331 | dst.type = OP_REG; | 1364 | c->dst.type = OP_REG; |
1332 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; | 1365 | c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes; |
1333 | dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX]; | 1366 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; |
1334 | if ((rc = ops->read_emulated(cr2, &dst.val, dst.bytes, | 1367 | if ((rc = ops->read_emulated(cr2, &c->dst.val, |
1368 | c->dst.bytes, | ||
1335 | ctxt->vcpu)) != 0) | 1369 | ctxt->vcpu)) != 0) |
1336 | goto done; | 1370 | goto done; |
1337 | register_address_increment(_regs[VCPU_REGS_RSI], | 1371 | register_address_increment(c->regs[VCPU_REGS_RSI], |
1338 | (_eflags & EFLG_DF) ? -dst.bytes : dst.bytes); | 1372 | (_eflags & EFLG_DF) ? -c->dst.bytes |
1373 | : c->dst.bytes); | ||
1339 | break; | 1374 | break; |
1340 | case 0xae ... 0xaf: /* scas */ | 1375 | case 0xae ... 0xaf: /* scas */ |
1341 | DPRINTF("Urk! I don't handle SCAS.\n"); | 1376 | DPRINTF("Urk! I don't handle SCAS.\n"); |
1342 | goto cannot_emulate; | 1377 | goto cannot_emulate; |
1343 | case 0xe8: /* call (near) */ { | 1378 | case 0xe8: /* call (near) */ { |
1344 | long int rel; | 1379 | long int rel; |
1345 | switch (op_bytes) { | 1380 | switch (c->op_bytes) { |
1346 | case 2: | 1381 | case 2: |
1347 | rel = insn_fetch(s16, 2, _eip); | 1382 | rel = insn_fetch(s16, 2, c->eip); |
1348 | break; | 1383 | break; |
1349 | case 4: | 1384 | case 4: |
1350 | rel = insn_fetch(s32, 4, _eip); | 1385 | rel = insn_fetch(s32, 4, c->eip); |
1351 | break; | 1386 | break; |
1352 | case 8: | 1387 | case 8: |
1353 | rel = insn_fetch(s64, 8, _eip); | 1388 | rel = insn_fetch(s64, 8, c->eip); |
1354 | break; | 1389 | break; |
1355 | default: | 1390 | default: |
1356 | DPRINTF("Call: Invalid op_bytes\n"); | 1391 | DPRINTF("Call: Invalid op_bytes\n"); |
1357 | goto cannot_emulate; | 1392 | goto cannot_emulate; |
1358 | } | 1393 | } |
1359 | src.val = (unsigned long) _eip; | 1394 | c->src.val = (unsigned long) c->eip; |
1360 | JMP_REL(rel); | 1395 | JMP_REL(rel); |
1361 | op_bytes = ad_bytes; | 1396 | c->op_bytes = c->ad_bytes; |
1362 | goto push; | 1397 | goto push; |
1363 | } | 1398 | } |
1364 | case 0xe9: /* jmp rel */ | 1399 | case 0xe9: /* jmp rel */ |
1365 | case 0xeb: /* jmp rel short */ | 1400 | case 0xeb: /* jmp rel short */ |
1366 | JMP_REL(src.val); | 1401 | JMP_REL(c->src.val); |
1367 | no_wb = 1; /* Disable writeback. */ | 1402 | no_wb = 1; /* Disable writeback. */ |
1368 | break; | 1403 | break; |
1369 | 1404 | ||
@@ -1372,16 +1407,16 @@ special_insn: | |||
1372 | goto writeback; | 1407 | goto writeback; |
1373 | 1408 | ||
1374 | twobyte_insn: | 1409 | twobyte_insn: |
1375 | switch (b) { | 1410 | switch (c->b) { |
1376 | case 0x01: /* lgdt, lidt, lmsw */ | 1411 | case 0x01: /* lgdt, lidt, lmsw */ |
1377 | /* Disable writeback. */ | 1412 | /* Disable writeback. */ |
1378 | no_wb = 1; | 1413 | no_wb = 1; |
1379 | switch (modrm_reg) { | 1414 | switch (c->modrm_reg) { |
1380 | u16 size; | 1415 | u16 size; |
1381 | unsigned long address; | 1416 | unsigned long address; |
1382 | 1417 | ||
1383 | case 0: /* vmcall */ | 1418 | case 0: /* vmcall */ |
1384 | if (modrm_mod != 3 || modrm_rm != 1) | 1419 | if (c->modrm_mod != 3 || c->modrm_rm != 1) |
1385 | goto cannot_emulate; | 1420 | goto cannot_emulate; |
1386 | 1421 | ||
1387 | rc = kvm_fix_hypercall(ctxt->vcpu); | 1422 | rc = kvm_fix_hypercall(ctxt->vcpu); |
@@ -1391,37 +1426,37 @@ twobyte_insn: | |||
1391 | kvm_emulate_hypercall(ctxt->vcpu); | 1426 | kvm_emulate_hypercall(ctxt->vcpu); |
1392 | break; | 1427 | break; |
1393 | case 2: /* lgdt */ | 1428 | case 2: /* lgdt */ |
1394 | rc = read_descriptor(ctxt, ops, src.ptr, | 1429 | rc = read_descriptor(ctxt, ops, c->src.ptr, |
1395 | &size, &address, op_bytes); | 1430 | &size, &address, c->op_bytes); |
1396 | if (rc) | 1431 | if (rc) |
1397 | goto done; | 1432 | goto done; |
1398 | realmode_lgdt(ctxt->vcpu, size, address); | 1433 | realmode_lgdt(ctxt->vcpu, size, address); |
1399 | break; | 1434 | break; |
1400 | case 3: /* lidt/vmmcall */ | 1435 | case 3: /* lidt/vmmcall */ |
1401 | if (modrm_mod == 3 && modrm_rm == 1) { | 1436 | if (c->modrm_mod == 3 && c->modrm_rm == 1) { |
1402 | rc = kvm_fix_hypercall(ctxt->vcpu); | 1437 | rc = kvm_fix_hypercall(ctxt->vcpu); |
1403 | if (rc) | 1438 | if (rc) |
1404 | goto done; | 1439 | goto done; |
1405 | kvm_emulate_hypercall(ctxt->vcpu); | 1440 | kvm_emulate_hypercall(ctxt->vcpu); |
1406 | } else { | 1441 | } else { |
1407 | rc = read_descriptor(ctxt, ops, src.ptr, | 1442 | rc = read_descriptor(ctxt, ops, c->src.ptr, |
1408 | &size, &address, | 1443 | &size, &address, |
1409 | op_bytes); | 1444 | c->op_bytes); |
1410 | if (rc) | 1445 | if (rc) |
1411 | goto done; | 1446 | goto done; |
1412 | realmode_lidt(ctxt->vcpu, size, address); | 1447 | realmode_lidt(ctxt->vcpu, size, address); |
1413 | } | 1448 | } |
1414 | break; | 1449 | break; |
1415 | case 4: /* smsw */ | 1450 | case 4: /* smsw */ |
1416 | if (modrm_mod != 3) | 1451 | if (c->modrm_mod != 3) |
1417 | goto cannot_emulate; | 1452 | goto cannot_emulate; |
1418 | *(u16 *)&_regs[modrm_rm] | 1453 | *(u16 *)&c->regs[c->modrm_rm] |
1419 | = realmode_get_cr(ctxt->vcpu, 0); | 1454 | = realmode_get_cr(ctxt->vcpu, 0); |
1420 | break; | 1455 | break; |
1421 | case 6: /* lmsw */ | 1456 | case 6: /* lmsw */ |
1422 | if (modrm_mod != 3) | 1457 | if (c->modrm_mod != 3) |
1423 | goto cannot_emulate; | 1458 | goto cannot_emulate; |
1424 | realmode_lmsw(ctxt->vcpu, (u16)modrm_val, &_eflags); | 1459 | realmode_lmsw(ctxt->vcpu, (u16)c->modrm_val, &_eflags); |
1425 | break; | 1460 | break; |
1426 | case 7: /* invlpg*/ | 1461 | case 7: /* invlpg*/ |
1427 | emulate_invlpg(ctxt->vcpu, cr2); | 1462 | emulate_invlpg(ctxt->vcpu, cr2); |
@@ -1432,24 +1467,26 @@ twobyte_insn: | |||
1432 | break; | 1467 | break; |
1433 | case 0x21: /* mov from dr to reg */ | 1468 | case 0x21: /* mov from dr to reg */ |
1434 | no_wb = 1; | 1469 | no_wb = 1; |
1435 | if (modrm_mod != 3) | 1470 | if (c->modrm_mod != 3) |
1436 | goto cannot_emulate; | 1471 | goto cannot_emulate; |
1437 | rc = emulator_get_dr(ctxt, modrm_reg, &_regs[modrm_rm]); | 1472 | rc = emulator_get_dr(ctxt, c->modrm_reg, |
1473 | &c->regs[c->modrm_rm]); | ||
1438 | break; | 1474 | break; |
1439 | case 0x23: /* mov from reg to dr */ | 1475 | case 0x23: /* mov from reg to dr */ |
1440 | no_wb = 1; | 1476 | no_wb = 1; |
1441 | if (modrm_mod != 3) | 1477 | if (c->modrm_mod != 3) |
1442 | goto cannot_emulate; | 1478 | goto cannot_emulate; |
1443 | rc = emulator_set_dr(ctxt, modrm_reg, _regs[modrm_rm]); | 1479 | rc = emulator_set_dr(ctxt, c->modrm_reg, |
1480 | c->regs[c->modrm_rm]); | ||
1444 | break; | 1481 | break; |
1445 | case 0x40 ... 0x4f: /* cmov */ | 1482 | case 0x40 ... 0x4f: /* cmov */ |
1446 | dst.val = dst.orig_val = src.val; | 1483 | c->dst.val = c->dst.orig_val = c->src.val; |
1447 | no_wb = 1; | 1484 | no_wb = 1; |
1448 | /* | 1485 | /* |
1449 | * First, assume we're decoding an even cmov opcode | 1486 | * First, assume we're decoding an even cmov opcode |
1450 | * (lsb == 0). | 1487 | * (lsb == 0). |
1451 | */ | 1488 | */ |
1452 | switch ((b & 15) >> 1) { | 1489 | switch ((c->b & 15) >> 1) { |
1453 | case 0: /* cmovo */ | 1490 | case 0: /* cmovo */ |
1454 | no_wb = (_eflags & EFLG_OF) ? 0 : 1; | 1491 | no_wb = (_eflags & EFLG_OF) ? 0 : 1; |
1455 | break; | 1492 | break; |
@@ -1477,46 +1514,50 @@ twobyte_insn: | |||
1477 | break; | 1514 | break; |
1478 | } | 1515 | } |
1479 | /* Odd cmov opcodes (lsb == 1) have inverted sense. */ | 1516 | /* Odd cmov opcodes (lsb == 1) have inverted sense. */ |
1480 | no_wb ^= b & 1; | 1517 | no_wb ^= c->b & 1; |
1481 | break; | 1518 | break; |
1482 | case 0xa3: | 1519 | case 0xa3: |
1483 | bt: /* bt */ | 1520 | bt: /* bt */ |
1484 | src.val &= (dst.bytes << 3) - 1; /* only subword offset */ | 1521 | /* only subword offset */ |
1485 | emulate_2op_SrcV_nobyte("bt", src, dst, _eflags); | 1522 | c->src.val &= (c->dst.bytes << 3) - 1; |
1523 | emulate_2op_SrcV_nobyte("bt", c->src, c->dst, _eflags); | ||
1486 | break; | 1524 | break; |
1487 | case 0xab: | 1525 | case 0xab: |
1488 | bts: /* bts */ | 1526 | bts: /* bts */ |
1489 | src.val &= (dst.bytes << 3) - 1; /* only subword offset */ | 1527 | /* only subword offset */ |
1490 | emulate_2op_SrcV_nobyte("bts", src, dst, _eflags); | 1528 | c->src.val &= (c->dst.bytes << 3) - 1; |
1529 | emulate_2op_SrcV_nobyte("bts", c->src, c->dst, _eflags); | ||
1491 | break; | 1530 | break; |
1492 | case 0xb0 ... 0xb1: /* cmpxchg */ | 1531 | case 0xb0 ... 0xb1: /* cmpxchg */ |
1493 | /* | 1532 | /* |
1494 | * Save real source value, then compare EAX against | 1533 | * Save real source value, then compare EAX against |
1495 | * destination. | 1534 | * destination. |
1496 | */ | 1535 | */ |
1497 | src.orig_val = src.val; | 1536 | c->src.orig_val = c->src.val; |
1498 | src.val = _regs[VCPU_REGS_RAX]; | 1537 | c->src.val = c->regs[VCPU_REGS_RAX]; |
1499 | emulate_2op_SrcV("cmp", src, dst, _eflags); | 1538 | emulate_2op_SrcV("cmp", c->src, c->dst, _eflags); |
1500 | if (_eflags & EFLG_ZF) { | 1539 | if (_eflags & EFLG_ZF) { |
1501 | /* Success: write back to memory. */ | 1540 | /* Success: write back to memory. */ |
1502 | dst.val = src.orig_val; | 1541 | c->dst.val = c->src.orig_val; |
1503 | } else { | 1542 | } else { |
1504 | /* Failure: write the value we saw to EAX. */ | 1543 | /* Failure: write the value we saw to EAX. */ |
1505 | dst.type = OP_REG; | 1544 | c->dst.type = OP_REG; |
1506 | dst.ptr = (unsigned long *)&_regs[VCPU_REGS_RAX]; | 1545 | c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX]; |
1507 | } | 1546 | } |
1508 | break; | 1547 | break; |
1509 | case 0xb3: | 1548 | case 0xb3: |
1510 | btr: /* btr */ | 1549 | btr: /* btr */ |
1511 | src.val &= (dst.bytes << 3) - 1; /* only subword offset */ | 1550 | /* only subword offset */ |
1512 | emulate_2op_SrcV_nobyte("btr", src, dst, _eflags); | 1551 | c->src.val &= (c->dst.bytes << 3) - 1; |
1552 | emulate_2op_SrcV_nobyte("btr", c->src, c->dst, _eflags); | ||
1513 | break; | 1553 | break; |
1514 | case 0xb6 ... 0xb7: /* movzx */ | 1554 | case 0xb6 ... 0xb7: /* movzx */ |
1515 | dst.bytes = op_bytes; | 1555 | c->dst.bytes = c->op_bytes; |
1516 | dst.val = (d & ByteOp) ? (u8) src.val : (u16) src.val; | 1556 | c->dst.val = (c->d & ByteOp) ? (u8) c->src.val |
1557 | : (u16) c->src.val; | ||
1517 | break; | 1558 | break; |
1518 | case 0xba: /* Grp8 */ | 1559 | case 0xba: /* Grp8 */ |
1519 | switch (modrm_reg & 3) { | 1560 | switch (c->modrm_reg & 3) { |
1520 | case 0: | 1561 | case 0: |
1521 | goto bt; | 1562 | goto bt; |
1522 | case 1: | 1563 | case 1: |
@@ -1529,16 +1570,19 @@ twobyte_insn: | |||
1529 | break; | 1570 | break; |
1530 | case 0xbb: | 1571 | case 0xbb: |
1531 | btc: /* btc */ | 1572 | btc: /* btc */ |
1532 | src.val &= (dst.bytes << 3) - 1; /* only subword offset */ | 1573 | /* only subword offset */ |
1533 | emulate_2op_SrcV_nobyte("btc", src, dst, _eflags); | 1574 | c->src.val &= (c->dst.bytes << 3) - 1; |
1575 | emulate_2op_SrcV_nobyte("btc", c->src, c->dst, _eflags); | ||
1534 | break; | 1576 | break; |
1535 | case 0xbe ... 0xbf: /* movsx */ | 1577 | case 0xbe ... 0xbf: /* movsx */ |
1536 | dst.bytes = op_bytes; | 1578 | c->dst.bytes = c->op_bytes; |
1537 | dst.val = (d & ByteOp) ? (s8) src.val : (s16) src.val; | 1579 | c->dst.val = (c->d & ByteOp) ? (s8) c->src.val : |
1580 | (s16) c->src.val; | ||
1538 | break; | 1581 | break; |
1539 | case 0xc3: /* movnti */ | 1582 | case 0xc3: /* movnti */ |
1540 | dst.bytes = op_bytes; | 1583 | c->dst.bytes = c->op_bytes; |
1541 | dst.val = (op_bytes == 4) ? (u32) src.val : (u64) src.val; | 1584 | c->dst.val = (c->op_bytes == 4) ? (u32) c->src.val : |
1585 | (u64) c->src.val; | ||
1542 | break; | 1586 | break; |
1543 | } | 1587 | } |
1544 | goto writeback; | 1588 | goto writeback; |
@@ -1546,7 +1590,7 @@ twobyte_insn: | |||
1546 | twobyte_special_insn: | 1590 | twobyte_special_insn: |
1547 | /* Disable writeback. */ | 1591 | /* Disable writeback. */ |
1548 | no_wb = 1; | 1592 | no_wb = 1; |
1549 | switch (b) { | 1593 | switch (c->b) { |
1550 | case 0x06: | 1594 | case 0x06: |
1551 | emulate_clts(ctxt->vcpu); | 1595 | emulate_clts(ctxt->vcpu); |
1552 | break; | 1596 | break; |
@@ -1558,56 +1602,59 @@ twobyte_special_insn: | |||
1558 | case 0x18: /* Grp16 (prefetch/nop) */ | 1602 | case 0x18: /* Grp16 (prefetch/nop) */ |
1559 | break; | 1603 | break; |
1560 | case 0x20: /* mov cr, reg */ | 1604 | case 0x20: /* mov cr, reg */ |
1561 | if (modrm_mod != 3) | 1605 | if (c->modrm_mod != 3) |
1562 | goto cannot_emulate; | 1606 | goto cannot_emulate; |
1563 | _regs[modrm_rm] = realmode_get_cr(ctxt->vcpu, modrm_reg); | 1607 | c->regs[c->modrm_rm] = |
1608 | realmode_get_cr(ctxt->vcpu, c->modrm_reg); | ||
1564 | break; | 1609 | break; |
1565 | case 0x22: /* mov reg, cr */ | 1610 | case 0x22: /* mov reg, cr */ |
1566 | if (modrm_mod != 3) | 1611 | if (c->modrm_mod != 3) |
1567 | goto cannot_emulate; | 1612 | goto cannot_emulate; |
1568 | realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); | 1613 | realmode_set_cr(ctxt->vcpu, |
1614 | c->modrm_reg, c->modrm_val, &_eflags); | ||
1569 | break; | 1615 | break; |
1570 | case 0x30: | 1616 | case 0x30: |
1571 | /* wrmsr */ | 1617 | /* wrmsr */ |
1572 | msr_data = (u32)_regs[VCPU_REGS_RAX] | 1618 | msr_data = (u32)c->regs[VCPU_REGS_RAX] |
1573 | | ((u64)_regs[VCPU_REGS_RDX] << 32); | 1619 | | ((u64)c->regs[VCPU_REGS_RDX] << 32); |
1574 | rc = kvm_set_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], msr_data); | 1620 | rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data); |
1575 | if (rc) { | 1621 | if (rc) { |
1576 | kvm_x86_ops->inject_gp(ctxt->vcpu, 0); | 1622 | kvm_x86_ops->inject_gp(ctxt->vcpu, 0); |
1577 | _eip = ctxt->vcpu->rip; | 1623 | c->eip = ctxt->vcpu->rip; |
1578 | } | 1624 | } |
1579 | rc = X86EMUL_CONTINUE; | 1625 | rc = X86EMUL_CONTINUE; |
1580 | break; | 1626 | break; |
1581 | case 0x32: | 1627 | case 0x32: |
1582 | /* rdmsr */ | 1628 | /* rdmsr */ |
1583 | rc = kvm_get_msr(ctxt->vcpu, _regs[VCPU_REGS_RCX], &msr_data); | 1629 | rc = kvm_get_msr(ctxt->vcpu, |
1630 | c->regs[VCPU_REGS_RCX], &msr_data); | ||
1584 | if (rc) { | 1631 | if (rc) { |
1585 | kvm_x86_ops->inject_gp(ctxt->vcpu, 0); | 1632 | kvm_x86_ops->inject_gp(ctxt->vcpu, 0); |
1586 | _eip = ctxt->vcpu->rip; | 1633 | c->eip = ctxt->vcpu->rip; |
1587 | } else { | 1634 | } else { |
1588 | _regs[VCPU_REGS_RAX] = (u32)msr_data; | 1635 | c->regs[VCPU_REGS_RAX] = (u32)msr_data; |
1589 | _regs[VCPU_REGS_RDX] = msr_data >> 32; | 1636 | c->regs[VCPU_REGS_RDX] = msr_data >> 32; |
1590 | } | 1637 | } |
1591 | rc = X86EMUL_CONTINUE; | 1638 | rc = X86EMUL_CONTINUE; |
1592 | break; | 1639 | break; |
1593 | case 0x80 ... 0x8f: /* jnz rel, etc*/ { | 1640 | case 0x80 ... 0x8f: /* jnz rel, etc*/ { |
1594 | long int rel; | 1641 | long int rel; |
1595 | 1642 | ||
1596 | switch (op_bytes) { | 1643 | switch (c->op_bytes) { |
1597 | case 2: | 1644 | case 2: |
1598 | rel = insn_fetch(s16, 2, _eip); | 1645 | rel = insn_fetch(s16, 2, c->eip); |
1599 | break; | 1646 | break; |
1600 | case 4: | 1647 | case 4: |
1601 | rel = insn_fetch(s32, 4, _eip); | 1648 | rel = insn_fetch(s32, 4, c->eip); |
1602 | break; | 1649 | break; |
1603 | case 8: | 1650 | case 8: |
1604 | rel = insn_fetch(s64, 8, _eip); | 1651 | rel = insn_fetch(s64, 8, c->eip); |
1605 | break; | 1652 | break; |
1606 | default: | 1653 | default: |
1607 | DPRINTF("jnz: Invalid op_bytes\n"); | 1654 | DPRINTF("jnz: Invalid op_bytes\n"); |
1608 | goto cannot_emulate; | 1655 | goto cannot_emulate; |
1609 | } | 1656 | } |
1610 | if (test_cc(b, _eflags)) | 1657 | if (test_cc(c->b, _eflags)) |
1611 | JMP_REL(rel); | 1658 | JMP_REL(rel); |
1612 | break; | 1659 | break; |
1613 | } | 1660 | } |
@@ -1617,14 +1664,16 @@ twobyte_special_insn: | |||
1617 | if ((rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu)) | 1664 | if ((rc = ops->read_emulated(cr2, &old, 8, ctxt->vcpu)) |
1618 | != 0) | 1665 | != 0) |
1619 | goto done; | 1666 | goto done; |
1620 | if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || | 1667 | if (((u32) (old >> 0) != |
1621 | ((u32) (old >> 32) != (u32) _regs[VCPU_REGS_RDX])) { | 1668 | (u32) c->regs[VCPU_REGS_RAX]) || |
1622 | _regs[VCPU_REGS_RAX] = (u32) (old >> 0); | 1669 | ((u32) (old >> 32) != |
1623 | _regs[VCPU_REGS_RDX] = (u32) (old >> 32); | 1670 | (u32) c->regs[VCPU_REGS_RDX])) { |
1671 | c->regs[VCPU_REGS_RAX] = (u32) (old >> 0); | ||
1672 | c->regs[VCPU_REGS_RDX] = (u32) (old >> 32); | ||
1624 | _eflags &= ~EFLG_ZF; | 1673 | _eflags &= ~EFLG_ZF; |
1625 | } else { | 1674 | } else { |
1626 | new = ((u64)_regs[VCPU_REGS_RCX] << 32) | 1675 | new = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
1627 | | (u32) _regs[VCPU_REGS_RBX]; | 1676 | | (u32) c->regs[VCPU_REGS_RBX]; |
1628 | if ((rc = ops->cmpxchg_emulated(cr2, &old, | 1677 | if ((rc = ops->cmpxchg_emulated(cr2, &old, |
1629 | &new, 8, ctxt->vcpu)) != 0) | 1678 | &new, 8, ctxt->vcpu)) != 0) |
1630 | goto done; | 1679 | goto done; |
@@ -1636,6 +1685,6 @@ twobyte_special_insn: | |||
1636 | goto writeback; | 1685 | goto writeback; |
1637 | 1686 | ||
1638 | cannot_emulate: | 1687 | cannot_emulate: |
1639 | DPRINTF("Cannot emulate %02x\n", b); | 1688 | DPRINTF("Cannot emulate %02x\n", c->b); |
1640 | return -1; | 1689 | return -1; |
1641 | } | 1690 | } |