diff mbox

[4/4] KVM: x86 emulator: Make x86_decode_insn() return proper macros

Message ID 20110730180334.2f50c753.takuya.yoshikawa@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Takuya Yoshikawa July 30, 2011, 9:03 a.m. UTC
From: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>

Return EMULATION_OK/FAILED consistently.  Also treat instruction fetch
errors, not restricted to X86EMUL_UNHANDLEABLE, as EMULATION_FAILED;
although this cannot happen in practice, the current logic will continue
the emulation even if the decoder fails to fetch the instruction.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
 arch/x86/kvm/emulate.c |   12 ++++++------
 arch/x86/kvm/x86.c     |    2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

Comments

Avi Kivity July 31, 2011, 8:48 a.m. UTC | #1
On 07/30/2011 12:03 PM, Takuya Yoshikawa wrote:
> From: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>
> Return EMULATION_OK/FAILED consistently.  Also treat instruction fetch
> errors, not restricted to X86EMUL_UNHANDLEABLE, as EMULATION_FAILED;
> although this cannot happen in practice, the current logic will continue
> the emulation even if the decoder fails to fetch the instruction.

In fact it can happen in practice, but not through normal usage.  For 
example, one vcpu can execute an instruction which traps into the 
emulator, while another vcpu changes the page tables to make the 
instruction unfetchable.
Takuya Yoshikawa July 31, 2011, 1:48 p.m. UTC | #2
On Sun, 31 Jul 2011 11:48:40 +0300
Avi Kivity <avi@redhat.com> wrote:

> On 07/30/2011 12:03 PM, Takuya Yoshikawa wrote:
> > From: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
> >
> > Return EMULATION_OK/FAILED consistently.  Also treat instruction fetch
> > errors, not restricted to X86EMUL_UNHANDLEABLE, as EMULATION_FAILED;
> > although this cannot happen in practice, the current logic will continue
> > the emulation even if the decoder fails to fetch the instruction.
> 
> In fact it can happen in practice, but not through normal usage.  For 
> example, one vcpu can execute an instruction which traps into the 
> emulator, while another vcpu changes the page tables to make the 
> instruction unfetchable.
> 

Really virtualization specific!
I need to think about multiple vcpus more.

Thanks,
  Takuya
diff mbox

Patch

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index ae8d23c..0453c07 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3373,7 +3373,7 @@  int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
 		break;
 #endif
 	default:
-		return -1;
+		return EMULATION_FAILED;
 	}
 
 	ctxt->op_bytes = def_op_bytes;
@@ -3465,7 +3465,7 @@  done_prefixes:
 			break;
 		case Prefix:
 			if (ctxt->rep_prefix && op_prefix)
-				return X86EMUL_UNHANDLEABLE;
+				return EMULATION_FAILED;
 			simd_prefix = op_prefix ? 0x66 : ctxt->rep_prefix;
 			switch (simd_prefix) {
 			case 0x00: opcode = opcode.u.gprefix->pfx_no; break;
@@ -3475,7 +3475,7 @@  done_prefixes:
 			}
 			break;
 		default:
-			return X86EMUL_UNHANDLEABLE;
+			return EMULATION_FAILED;
 		}
 
 		ctxt->d &= ~GroupMask;
@@ -3488,10 +3488,10 @@  done_prefixes:
 
 	/* Unrecognised? */
 	if (ctxt->d == 0 || (ctxt->d & Undefined))
-		return -1;
+		return EMULATION_FAILED;
 
 	if (!(ctxt->d & VendorSpecific) && ctxt->only_vendor_specific_insn)
-		return -1;
+		return EMULATION_FAILED;
 
 	if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack))
 		ctxt->op_bytes = 8;
@@ -3683,7 +3683,7 @@  done:
 	if (memopp && memopp->type == OP_MEM && ctxt->rip_relative)
 		memopp->addr.mem.ea += ctxt->_eip;
 
-	return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
+	return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
 }
 
 static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6cb353c..baa427a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4833,7 +4833,7 @@  int x86_emulate_instruction(struct kvm_vcpu *vcpu,
 
 		trace_kvm_emulate_insn_start(vcpu);
 		++vcpu->stat.insn_emulation;
-		if (r)  {
+		if (r != EMULATION_OK)  {
 			if (emulation_type & EMULTYPE_TRAP_UD)
 				return EMULATE_FAIL;
 			if (reexecute_instruction(vcpu, cr2))