diff options
author | Avi Kivity <avi@qumranet.com> | 2008-06-16 01:09:11 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-07-20 05:42:34 -0400 |
commit | f5b4edcd52e78556800f90d08bfc9126416ac82f (patch) | |
tree | 5c40b9781cf18d66c9e71b837ffc3eaddac48ddb /arch/x86/kvm | |
parent | 84411d85dacdb6665578608c6a70fc8b819761a8 (diff) |
KVM: x86 emulator: simplify rip relative decoding
rip relative decoding is relative to the instruction pointer of the next
instruction; by moving address adjustment until after decoding is complete,
we remove the need to determine the instruction size.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 23 |
1 files changed, 5 insertions, 18 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index c3a823174f3e..20b604489c3c 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -664,7 +664,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, | |||
664 | { | 664 | { |
665 | struct decode_cache *c = &ctxt->decode; | 665 | struct decode_cache *c = &ctxt->decode; |
666 | u8 sib; | 666 | u8 sib; |
667 | int index_reg = 0, base_reg = 0, scale, rip_relative = 0; | 667 | int index_reg = 0, base_reg = 0, scale; |
668 | int rc = 0; | 668 | int rc = 0; |
669 | 669 | ||
670 | if (c->rex_prefix) { | 670 | if (c->rex_prefix) { |
@@ -754,7 +754,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, | |||
754 | c->modrm_ea += c->regs[index_reg] << scale; | 754 | c->modrm_ea += c->regs[index_reg] << scale; |
755 | } else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) { | 755 | } else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) { |
756 | if (ctxt->mode == X86EMUL_MODE_PROT64) | 756 | if (ctxt->mode == X86EMUL_MODE_PROT64) |
757 | rip_relative = 1; | 757 | c->rip_relative = 1; |
758 | } else | 758 | } else |
759 | c->modrm_ea += c->regs[c->modrm_rm]; | 759 | c->modrm_ea += c->regs[c->modrm_rm]; |
760 | switch (c->modrm_mod) { | 760 | switch (c->modrm_mod) { |
@@ -770,22 +770,6 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt, | |||
770 | break; | 770 | break; |
771 | } | 771 | } |
772 | } | 772 | } |
773 | if (rip_relative) { | ||
774 | c->modrm_ea += c->eip; | ||
775 | switch (c->d & SrcMask) { | ||
776 | case SrcImmByte: | ||
777 | c->modrm_ea += 1; | ||
778 | break; | ||
779 | case SrcImm: | ||
780 | if (c->d & ByteOp) | ||
781 | c->modrm_ea += 1; | ||
782 | else | ||
783 | if (c->op_bytes == 8) | ||
784 | c->modrm_ea += 4; | ||
785 | else | ||
786 | c->modrm_ea += c->op_bytes; | ||
787 | } | ||
788 | } | ||
789 | done: | 773 | done: |
790 | return rc; | 774 | return rc; |
791 | } | 775 | } |
@@ -1044,6 +1028,9 @@ done_prefixes: | |||
1044 | break; | 1028 | break; |
1045 | } | 1029 | } |
1046 | 1030 | ||
1031 | if (c->rip_relative) | ||
1032 | c->modrm_ea += c->eip; | ||
1033 | |||
1047 | done: | 1034 | done: |
1048 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; | 1035 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; |
1049 | } | 1036 | } |