svn commit: r253585 - head/sys/amd64/vmm

Neel Natu neel at FreeBSD.org
Tue Jul 23 23:43:02 UTC 2013


Author: neel
Date: Tue Jul 23 23:43:00 2013
New Revision: 253585
URL: http://svnweb.freebsd.org/changeset/base/253585

Log:
  Add support for emulation of the "or r/m, imm8" instruction.
  
  Submitted by:	Zhixiang Yu (zxyu.core at gmail.com)
  Obtained from:	GSoC 2013 (AHCI device emulation for bhyve)

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	Tue Jul 23 22:53:01 2013	(r253584)
+++ head/sys/amd64/vmm/vmm_instruction_emul.c	Tue Jul 23 23:43:00 2013	(r253585)
@@ -60,6 +60,7 @@ enum {
 	VIE_OP_TYPE_NONE = 0,
 	VIE_OP_TYPE_MOV,
 	VIE_OP_TYPE_AND,
+	VIE_OP_TYPE_OR,
 	VIE_OP_TYPE_LAST
 };
 
@@ -94,7 +95,13 @@ static const struct vie_op one_byte_opco
 		.op_byte = 0x81,
 		.op_type = VIE_OP_TYPE_AND,
 		.op_flags = VIE_OP_F_IMM,
-	}
+	},
+	[0x83] = {
+		/* XXX Group 1 extended opcode - not just OR */
+		.op_byte = 0x83,
+		.op_type = VIE_OP_TYPE_OR,
+		.op_flags = VIE_OP_F_IMM8,
+	},
 };
 
 /* struct vie.mod */
@@ -338,8 +345,8 @@ emulate_and(void *vm, int vcpuid, uint64
 		break;
 	case 0x81:
 		/*
-		 * AND reg (ModRM:reg) with immediate and store the
-		 * result in reg
+		 * AND mem (ModRM:r/m) with immediate and store the
+		 * result in mem.
 		 *
 		 * 81/          and r/m32, imm32
 		 * REX.W + 81/  and r/m64, imm32 sign-extended to 64
@@ -371,6 +378,52 @@ emulate_and(void *vm, int vcpuid, uint64
 	return (error);
 }
 
+static int
+emulate_or(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;
+	uint64_t val1;
+
+	size = 4;
+	error = EINVAL;
+
+	switch (vie->op.op_byte) {
+	case 0x83:
+		/*
+		 * OR mem (ModRM:r/m) with immediate and store the
+		 * result in mem.
+		 *
+		 * 83/          OR r/m32, imm8 sign-extended to 32
+		 * REX.W + 83/  OR r/m64, imm8 sign-extended to 64
+		 *
+		 * Currently, only the OR operation of the 0x83 opcode
+		 * is implemented (ModRM:reg = b001).
+		 */
+		if ((vie->reg & 7) != 1)
+			break;
+
+		if (vie->rex_w)
+			size = 8;
+		
+		/* get the first operand */
+                error = memread(vm, vcpuid, gpa, &val1, size, arg);
+                if (error)
+			break;
+
+                /*
+		 * perform the operation with the pre-fetched immediate
+		 * operand and write the result
+		 */
+                val1 |= vie->immediate;
+                error = memwrite(vm, vcpuid, gpa, val1, size, arg);
+		break;
+	default:
+		break;
+	}
+	return (error);
+}
+
 int
 vmm_emulate_instruction(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
 			mem_region_read_t memread, mem_region_write_t memwrite,
@@ -390,6 +443,10 @@ vmm_emulate_instruction(void *vm, int vc
 		error = emulate_and(vm, vcpuid, gpa, vie,
 				    memread, memwrite, memarg);
 		break;
+	case VIE_OP_TYPE_OR:
+		error = emulate_or(vm, vcpuid, gpa, vie,
+				    memread, memwrite, memarg);
+		break;
 	default:
 		error = EINVAL;
 		break;


More information about the svn-src-all mailing list