From owner-svn-src-all@FreeBSD.ORG Wed Jan 30 04:09:10 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 496491A4; Wed, 30 Jan 2013 04:09:10 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 37C8DB7C; Wed, 30 Jan 2013 04:09:10 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0U49Au2080097; Wed, 30 Jan 2013 04:09:10 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0U499Bm080094; Wed, 30 Jan 2013 04:09:09 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201301300409.r0U499Bm080094@svn.freebsd.org> From: Neel Natu Date: Wed, 30 Jan 2013 04:09:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r246108 - in head/sys/amd64: include vmm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Jan 2013 04:09:10 -0000 Author: neel Date: Wed Jan 30 04:09:09 2013 New Revision: 246108 URL: http://svnweb.freebsd.org/changeset/base/246108 Log: Add emulation support for instruction "88/r: mov r/m8, r8". This instruction moves a byte from a register to a memory location. Tested by: tycho nightingale at pluribusnetworks com Modified: head/sys/amd64/include/vmm_instruction_emul.h head/sys/amd64/vmm/vmm_instruction_emul.c Modified: head/sys/amd64/include/vmm_instruction_emul.h ============================================================================== --- head/sys/amd64/include/vmm_instruction_emul.h Wed Jan 30 01:43:00 2013 (r246107) +++ head/sys/amd64/include/vmm_instruction_emul.h Wed Jan 30 04:09:09 2013 (r246108) @@ -49,7 +49,8 @@ struct vie { uint8_t rex_w:1, /* REX prefix */ rex_r:1, rex_x:1, - rex_b:1; + rex_b:1, + rex_present:1; uint8_t mod:2, /* ModRM byte */ reg:4, Modified: head/sys/amd64/vmm/vmm_instruction_emul.c ============================================================================== --- head/sys/amd64/vmm/vmm_instruction_emul.c Wed Jan 30 01:43:00 2013 (r246107) +++ head/sys/amd64/vmm/vmm_instruction_emul.c Wed Jan 30 04:09:09 2013 (r246108) @@ -65,6 +65,10 @@ enum { #define VIE_OP_F_IMM8 (1 << 1) /* 8-bit immediate operand */ static const struct vie_op one_byte_opcodes[256] = { + [0x88] = { + .op_byte = 0x88, + .op_type = VIE_OP_TYPE_MOV, + }, [0x89] = { .op_byte = 0x89, .op_type = VIE_OP_TYPE_MOV, @@ -161,6 +165,46 @@ vie_read_register(void *vm, int vcpuid, } static int +vie_read_bytereg(void *vm, int vcpuid, struct vie *vie, uint8_t *rval) +{ + uint64_t val; + int error, rshift; + enum vm_reg_name reg; + + rshift = 0; + reg = gpr_map[vie->reg]; + + /* + * 64-bit mode imposes limitations on accessing legacy byte registers. + * + * The legacy high-byte registers cannot be addressed if the REX + * prefix is present. In this case the values 4, 5, 6 and 7 of the + * 'ModRM:reg' field address %spl, %bpl, %sil and %dil respectively. + * + * If the REX prefix is not present then the values 4, 5, 6 and 7 + * of the 'ModRM:reg' field address the legacy high-byte registers, + * %ah, %ch, %dh and %bh respectively. + */ + if (!vie->rex_present) { + if (vie->reg & 0x4) { + /* + * Obtain the value of %ah by reading %rax and shifting + * right by 8 bits (same for %bh, %ch and %dh). + */ + rshift = 8; + reg = gpr_map[vie->reg & 0x3]; + } + } + + if (!vie_valid_register(reg)) + return (EINVAL); + + error = vm_get_register(vm, vcpuid, reg, &val); + *rval = val >> rshift; + return (error); +} + +static int vie_update_register(void *vm, int vcpuid, enum vm_reg_name reg, uint64_t val, int size) { @@ -209,12 +253,24 @@ emulate_mov(void *vm, int vcpuid, uint64 { int error, size; enum vm_reg_name reg; + uint8_t byte; uint64_t val; size = 4; error = EINVAL; switch (vie->op.op_byte) { + case 0x88: + /* + * MOV byte from reg (ModRM:reg) to mem (ModRM:r/m) + * 88/r: mov r/m8, r8 + * REX + 88/r: mov r/m8, r8 (%ah, %ch, %dh, %bh not available) + */ + size = 1; + error = vie_read_bytereg(vm, vcpuid, vie, &byte); + if (error == 0) + error = memwrite(vm, vcpuid, gpa, byte, size, arg); + break; case 0x89: /* * MOV from reg (ModRM:reg) to mem (ModRM:r/m) @@ -497,6 +553,8 @@ decode_rex(struct vie *vie) return (-1); if (x >= 0x40 && x <= 0x4F) { + vie->rex_present = 1; + vie->rex_w = x & 0x8 ? 1 : 0; vie->rex_r = x & 0x4 ? 1 : 0; vie->rex_x = x & 0x2 ? 1 : 0;