All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takuya Yoshikawa <takuya.yoshikawa@gmail.com>
To: avi@redhat.com, mtosatti@redhat.com
Cc: kvm@vger.kernel.org, yoshikawa.takuya@oss.ntt.co.jp
Subject: [PATCH 2/4] KVM: x86 emulator: Make prefix decoding a separate function
Date: Tue, 24 Apr 2012 00:34:32 +0900	[thread overview]
Message-ID: <20120424003432.b4a9ef17d37dd6201d448390@gmail.com> (raw)
In-Reply-To: <20120424003159.4fd245ec18b0b3eeddbea553@gmail.com>

From: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>

Instruction decoding can be split into separate parts, and this is the
first one which treats the instruction prefixes.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Cc: Takuya Yoshikawa <takuya.yoshikawa@gmail.com>
---
 arch/x86/kvm/emulate.c |   58 +++++++++++++++++++++++++++++++----------------
 1 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 5a49290..b22238b 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3874,22 +3874,21 @@ done:
 	return rc;
 }
 
-int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
+/**
+ * decode_prefixes - decode instruction prefixes
+ * @ctxt: emulation context
+ *
+ * Fetches instruction prefixes and sets some ctxt fields based on them.
+ * The byte next to the last prefix is also fetched into ctxt->b.
+ *
+ * Returns X86EMUL_CONTINUE on success.
+ */
+static int decode_prefixes(struct x86_emulate_ctxt *ctxt)
 {
 	int rc = X86EMUL_CONTINUE;
-	int mode = ctxt->mode;
-	int def_op_bytes, def_ad_bytes, goffset, simd_prefix;
-	struct opcode opcode;
+	int def_op_bytes, def_ad_bytes;
 
-	ctxt->memop.type = OP_NONE;
-	ctxt->memopp = NULL;
-	ctxt->_eip = ctxt->eip;
-	ctxt->fetch.start = ctxt->_eip;
-	ctxt->fetch.end = ctxt->fetch.start + insn_len;
-	if (insn_len > 0)
-		memcpy(ctxt->fetch.data, insn, insn_len);
-
-	switch (mode) {
+	switch (ctxt->mode) {
 	case X86EMUL_MODE_REAL:
 	case X86EMUL_MODE_VM86:
 	case X86EMUL_MODE_PROT16:
@@ -3905,7 +3904,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
 		break;
 #endif
 	default:
-		return EMULATION_FAILED;
+		return X86EMUL_UNHANDLEABLE;
 	}
 
 	ctxt->op_bytes = def_op_bytes;
@@ -3920,7 +3919,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
 			ctxt->op_bytes = def_op_bytes ^ 6;
 			break;
 		case 0x67:	/* address-size override */
-			if (mode == X86EMUL_MODE_PROT64)
+			if (ctxt->mode == X86EMUL_MODE_PROT64)
 				/* switch between 4/8 bytes */
 				ctxt->ad_bytes = def_ad_bytes ^ 12;
 			else
@@ -3938,7 +3937,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
 			set_seg_override(ctxt, ctxt->b & 7);
 			break;
 		case 0x40 ... 0x4f: /* REX */
-			if (mode != X86EMUL_MODE_PROT64)
+			if (ctxt->mode != X86EMUL_MODE_PROT64)
 				goto done_prefixes;
 			ctxt->rex_prefix = ctxt->b;
 			continue;
@@ -3954,15 +3953,34 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
 		}
 
 		/* Any legacy prefix after a REX prefix nullifies its effect. */
-
 		ctxt->rex_prefix = 0;
 	}
 
 done_prefixes:
-
 	/* REX prefix. */
 	if (ctxt->rex_prefix & 8)
 		ctxt->op_bytes = 8;	/* REX.W */
+done:
+	return rc;
+}
+
+int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
+{
+	int rc = X86EMUL_CONTINUE;
+	int goffset, simd_prefix;
+	struct opcode opcode;
+
+	ctxt->memop.type = OP_NONE;
+	ctxt->memopp = NULL;
+	ctxt->_eip = ctxt->eip;
+	ctxt->fetch.start = ctxt->_eip;
+	ctxt->fetch.end = ctxt->fetch.start + insn_len;
+	if (insn_len > 0)
+		memcpy(ctxt->fetch.data, insn, insn_len);
+
+	rc = decode_prefixes(ctxt);
+	if (rc != X86EMUL_CONTINUE)
+		goto done;
 
 	/* Opcode byte(s). */
 	opcode = opcode_table[ctxt->b];
@@ -4025,11 +4043,11 @@ done_prefixes:
 	if (!(ctxt->d & VendorSpecific) && ctxt->only_vendor_specific_insn)
 		return EMULATION_FAILED;
 
-	if (mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack))
+	if (ctxt->mode == X86EMUL_MODE_PROT64 && (ctxt->d & Stack))
 		ctxt->op_bytes = 8;
 
 	if (ctxt->d & Op3264) {
-		if (mode == X86EMUL_MODE_PROT64)
+		if (ctxt->mode == X86EMUL_MODE_PROT64)
 			ctxt->op_bytes = 8;
 		else
 			ctxt->op_bytes = 4;
-- 
1.7.5.4


  parent reply	other threads:[~2012-04-23 15:34 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-23 15:31 [PATCH 0/4] KVM: x86 emulator: Split decoder into separate functions Takuya Yoshikawa
2012-04-23 15:33 ` [PATCH 1/4] KVM: x86 emulator: Introduce ctxt->op_prefix for 0x66 prefix Takuya Yoshikawa
2012-04-23 15:34 ` Takuya Yoshikawa [this message]
2012-04-23 15:35 ` [PATCH 3/4] KVM: x86 emulator: Make opcode decoding a separate function Takuya Yoshikawa
2012-04-23 15:37 ` [PATCH 4/4] KVM: x86 emulator: Avoid pushing back ModRM byte in decode_opcode() Takuya Yoshikawa
2012-04-24 14:10   ` Avi Kivity
2012-04-24 14:27     ` Takuya Yoshikawa
2012-04-24 14:11 ` [PATCH 0/4] KVM: x86 emulator: Split decoder into separate functions Avi Kivity
2012-04-24 14:41   ` Takuya Yoshikawa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120424003432.b4a9ef17d37dd6201d448390@gmail.com \
    --to=takuya.yoshikawa@gmail.com \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    --cc=yoshikawa.takuya@oss.ntt.co.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.