diff options
author | Borislav Petkov <bp@suse.de> | 2013-09-22 10:44:51 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-10-30 13:54:39 -0400 |
commit | 1ce19dc16ce9136cccb6087e4a383ec9321980d9 (patch) | |
tree | e93153a04096bf907dee183cc4b2260c5752991f | |
parent | 9c15bb1d0a8411f9bb3395d21d5309bde7da0c1c (diff) |
kvm, emulator: Use opcode length
Add a field to the current emulation context which contains the
instruction opcode length. This will streamline handling of opcodes of
different length.
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/include/asm/kvm_emulate.h | 8 | ||||
-rw-r--r-- | arch/x86/kvm/emulate.c | 5 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 4 |
3 files changed, 11 insertions, 6 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index 15f960c06ff7..92a176ad456c 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h | |||
@@ -279,8 +279,12 @@ struct x86_emulate_ctxt { | |||
279 | bool have_exception; | 279 | bool have_exception; |
280 | struct x86_exception exception; | 280 | struct x86_exception exception; |
281 | 281 | ||
282 | /* decode cache */ | 282 | /* |
283 | u8 twobyte; | 283 | * decode cache |
284 | */ | ||
285 | |||
286 | /* current opcode length in bytes */ | ||
287 | u8 opcode_len; | ||
284 | u8 b; | 288 | u8 b; |
285 | u8 intercept; | 289 | u8 intercept; |
286 | u8 lock_prefix; | 290 | u8 lock_prefix; |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index ddc3f3d2afdb..d554d96afbca 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -4126,6 +4126,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) | |||
4126 | ctxt->_eip = ctxt->eip; | 4126 | ctxt->_eip = ctxt->eip; |
4127 | ctxt->fetch.start = ctxt->_eip; | 4127 | ctxt->fetch.start = ctxt->_eip; |
4128 | ctxt->fetch.end = ctxt->fetch.start + insn_len; | 4128 | ctxt->fetch.end = ctxt->fetch.start + insn_len; |
4129 | ctxt->opcode_len = 1; | ||
4129 | if (insn_len > 0) | 4130 | if (insn_len > 0) |
4130 | memcpy(ctxt->fetch.data, insn, insn_len); | 4131 | memcpy(ctxt->fetch.data, insn, insn_len); |
4131 | 4132 | ||
@@ -4208,7 +4209,7 @@ done_prefixes: | |||
4208 | opcode = opcode_table[ctxt->b]; | 4209 | opcode = opcode_table[ctxt->b]; |
4209 | /* Two-byte opcode? */ | 4210 | /* Two-byte opcode? */ |
4210 | if (ctxt->b == 0x0f) { | 4211 | if (ctxt->b == 0x0f) { |
4211 | ctxt->twobyte = 1; | 4212 | ctxt->opcode_len = 2; |
4212 | ctxt->b = insn_fetch(u8, ctxt); | 4213 | ctxt->b = insn_fetch(u8, ctxt); |
4213 | opcode = twobyte_table[ctxt->b]; | 4214 | opcode = twobyte_table[ctxt->b]; |
4214 | } | 4215 | } |
@@ -4540,7 +4541,7 @@ special_insn: | |||
4540 | goto writeback; | 4541 | goto writeback; |
4541 | } | 4542 | } |
4542 | 4543 | ||
4543 | if (ctxt->twobyte) | 4544 | if (ctxt->opcode_len == 2) |
4544 | goto twobyte_insn; | 4545 | goto twobyte_insn; |
4545 | 4546 | ||
4546 | switch (ctxt->b) { | 4547 | switch (ctxt->b) { |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3d1e3ee8b39e..d00d88455fef 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -4789,8 +4789,8 @@ static void inject_emulated_exception(struct kvm_vcpu *vcpu) | |||
4789 | 4789 | ||
4790 | static void init_decode_cache(struct x86_emulate_ctxt *ctxt) | 4790 | static void init_decode_cache(struct x86_emulate_ctxt *ctxt) |
4791 | { | 4791 | { |
4792 | memset(&ctxt->twobyte, 0, | 4792 | memset(&ctxt->opcode_len, 0, |
4793 | (void *)&ctxt->_regs - (void *)&ctxt->twobyte); | 4793 | (void *)&ctxt->_regs - (void *)&ctxt->opcode_len); |
4794 | 4794 | ||
4795 | ctxt->fetch.start = 0; | 4795 | ctxt->fetch.start = 0; |
4796 | ctxt->fetch.end = 0; | 4796 | ctxt->fetch.end = 0; |