Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Feb 2014 02:01:08 +0000 (UTC)
From:      Tycho Nightingale <tychon@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r261503 - head/sys/amd64/vmm
Message-ID:  <201402050201.s15218tN075138@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tychon
Date: Wed Feb  5 02:01:08 2014
New Revision: 261503
URL: http://svnweb.freebsd.org/changeset/base/261503

Log:
  Add support for emulating the byte move and zero extend instructions:
  "mov r/m8, r32" and "mov r/m8, r64".
  
  Approved by:	neel (co-mentor)

Modified:
  head/sys/amd64/vmm/vmm_instruction_emul.c

Modified: head/sys/amd64/vmm/vmm_instruction_emul.c
==============================================================================
--- head/sys/amd64/vmm/vmm_instruction_emul.c	Wed Feb  5 02:00:31 2014	(r261502)
+++ head/sys/amd64/vmm/vmm_instruction_emul.c	Wed Feb  5 02:01:08 2014	(r261503)
@@ -58,8 +58,10 @@ enum cpu_mode {
 enum {
 	VIE_OP_TYPE_NONE = 0,
 	VIE_OP_TYPE_MOV,
+	VIE_OP_TYPE_MOVZX,
 	VIE_OP_TYPE_AND,
 	VIE_OP_TYPE_OR,
+	VIE_OP_TYPE_TWO_BYTE,
 	VIE_OP_TYPE_LAST
 };
 
@@ -67,7 +69,18 @@ enum {
 #define	VIE_OP_F_IMM		(1 << 0)	/* immediate operand present */
 #define	VIE_OP_F_IMM8		(1 << 1)	/* 8-bit immediate operand */
 
+static const struct vie_op two_byte_opcodes[256] = {
+	[0xB6] = {
+		.op_byte = 0xB6,
+		.op_type = VIE_OP_TYPE_MOVZX,
+	},
+};
+
 static const struct vie_op one_byte_opcodes[256] = {
+	[0x0F] = {
+		.op_byte = 0x0F,
+		.op_type = VIE_OP_TYPE_TWO_BYTE
+	},
 	[0x88] = {
 		.op_byte = 0x88,
 		.op_type = VIE_OP_TYPE_MOV,
@@ -313,6 +326,59 @@ emulate_mov(void *vm, int vcpuid, uint64
 	return (error);
 }
 
+/*
+ * The following simplifying assumptions are made during emulation:
+ *
+ * - guest is in 64-bit mode
+ *   - default address size is 64-bits
+ *   - default operand size is 32-bits
+ *
+ * - operand size override is not supported
+ *
+ * - address size override is not supported
+ */
+static int
+emulate_movzx(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
+	      mem_region_read_t memread, mem_region_write_t memwrite,
+	      void *arg)
+{
+	int error, size;
+	enum vm_reg_name reg;
+	uint64_t val;
+
+	size = 4;
+	error = EINVAL;
+
+	switch (vie->op.op_byte) {
+	case 0xB6:
+		/*
+		 * MOV and zero extend byte from mem (ModRM:r/m) to
+		 * reg (ModRM:reg).
+		 *
+		 * 0F B6/r		movzx r/m8, r32
+		 * REX.W + 0F B6/r	movzx r/m8, r64
+		 */
+
+		/* get the first operand */
+		error = memread(vm, vcpuid, gpa, &val, 1, arg);
+		if (error)
+			break;
+
+		/* get the second operand */
+		reg = gpr_map[vie->reg];
+
+		if (vie->rex_w)
+			size = 8;
+
+		/* write the result */
+		error = vie_update_register(vm, vcpuid, reg, val, size);
+		break;
+	default:
+		break;
+	}
+	return (error);
+}
+
 static int
 emulate_and(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
 	    mem_region_read_t memread, mem_region_write_t memwrite, void *arg)
@@ -447,6 +513,10 @@ vmm_emulate_instruction(void *vm, int vc
 		error = emulate_mov(vm, vcpuid, gpa, vie,
 				    memread, memwrite, memarg);
 		break;
+	case VIE_OP_TYPE_MOVZX:
+		error = emulate_movzx(vm, vcpuid, gpa, vie,
+				      memread, memwrite, memarg);
+		break;
 	case VIE_OP_TYPE_AND:
 		error = emulate_and(vm, vcpuid, gpa, vie,
 				    memread, memwrite, memarg);
@@ -609,6 +679,23 @@ decode_rex(struct vie *vie)
 }
 
 static int
+decode_two_byte_opcode(struct vie *vie)
+{
+	uint8_t x;
+
+	if (vie_peek(vie, &x))
+		return (-1);
+
+	vie->op = two_byte_opcodes[x];
+
+	if (vie->op.op_type == VIE_OP_TYPE_NONE)
+		return (-1);
+
+	vie_advance(vie);
+	return (0);
+}
+
+static int
 decode_opcode(struct vie *vie)
 {
 	uint8_t x;
@@ -622,6 +709,10 @@ decode_opcode(struct vie *vie)
 		return (-1);
 
 	vie_advance(vie);
+
+	if (vie->op.op_type == VIE_OP_TYPE_TWO_BYTE)
+		return (decode_two_byte_opcode(vie));
+
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402050201.s15218tN075138>