aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2013-09-22 10:44:51 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2013-10-30 13:54:39 -0400
commit1ce19dc16ce9136cccb6087e4a383ec9321980d9 (patch)
treee93153a04096bf907dee183cc4b2260c5752991f
parent9c15bb1d0a8411f9bb3395d21d5309bde7da0c1c (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.h8
-rw-r--r--arch/x86/kvm/emulate.c5
-rw-r--r--arch/x86/kvm/x86.c4
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
4790static void init_decode_cache(struct x86_emulate_ctxt *ctxt) 4790static 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;