Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 May 2014 20:26:58 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r266627 - in head: sys/amd64/include sys/amd64/vmm sys/amd64/vmm/intel usr.sbin/bhyve
Message-ID:  <201405242026.s4OKQwb2089232@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Sat May 24 20:26:57 2014
New Revision: 266627
URL: http://svnweb.freebsd.org/changeset/base/266627

Log:
  Consolidate all the information needed by the guest page table walker into
  'struct vm_guest_paging'.
  
  Check for canonical addressing in vmm_gla2gpa() and inject a protection
  fault into the guest if a violation is detected.
  
  If the page table walk is restarted in vmm_gla2gpa() then reset 'ptpphys' to
  point to the root of the page tables.

Modified:
  head/sys/amd64/include/vmm.h
  head/sys/amd64/include/vmm_instruction_emul.h
  head/sys/amd64/vmm/intel/vmx.c
  head/sys/amd64/vmm/vmm.c
  head/sys/amd64/vmm/vmm_instruction_emul.c
  head/sys/amd64/vmm/vmm_ioport.c
  head/usr.sbin/bhyve/inout.c
  head/usr.sbin/bhyve/mem.c

Modified: head/sys/amd64/include/vmm.h
==============================================================================
--- head/sys/amd64/include/vmm.h	Sat May 24 19:13:25 2014	(r266626)
+++ head/sys/amd64/include/vmm.h	Sat May 24 20:26:57 2014	(r266627)
@@ -243,8 +243,6 @@ enum vm_reg_name vm_segment_name(int seg
 
 #endif	/* KERNEL */
 
-#include <machine/vmm_instruction_emul.h>
-
 #define	VM_MAXCPU	16			/* maximum virtual cpus */
 
 /*
@@ -324,6 +322,71 @@ struct seg_desc {
 	uint32_t	access;
 };
 
+enum vm_cpu_mode {
+	CPU_MODE_COMPATIBILITY,		/* IA-32E mode (CS.L = 0) */
+	CPU_MODE_64BIT,			/* IA-32E mode (CS.L = 1) */
+};
+
+enum vm_paging_mode {
+	PAGING_MODE_FLAT,
+	PAGING_MODE_32,
+	PAGING_MODE_PAE,
+	PAGING_MODE_64,
+};
+
+struct vm_guest_paging {
+	uint64_t	cr3;
+	int		cpl;
+	enum vm_cpu_mode cpu_mode;
+	enum vm_paging_mode paging_mode;
+};
+
+/*
+ * The data structures 'vie' and 'vie_op' are meant to be opaque to the
+ * consumers of instruction decoding. The only reason why their contents
+ * need to be exposed is because they are part of the 'vm_exit' structure.
+ */
+struct vie_op {
+	uint8_t		op_byte;	/* actual opcode byte */
+	uint8_t		op_type;	/* type of operation (e.g. MOV) */
+	uint16_t	op_flags;
+};
+
+#define	VIE_INST_SIZE	15
+struct vie {
+	uint8_t		inst[VIE_INST_SIZE];	/* instruction bytes */
+	uint8_t		num_valid;		/* size of the instruction */
+	uint8_t		num_processed;
+
+	uint8_t		rex_w:1,		/* REX prefix */
+			rex_r:1,
+			rex_x:1,
+			rex_b:1,
+			rex_present:1;
+
+	uint8_t		mod:2,			/* ModRM byte */
+			reg:4,
+			rm:4;
+
+	uint8_t		ss:2,			/* SIB byte */
+			index:4,
+			base:4;
+
+	uint8_t		disp_bytes;
+	uint8_t		imm_bytes;
+
+	uint8_t		scale;
+	int		base_register;		/* VM_REG_GUEST_xyz */
+	int		index_register;		/* VM_REG_GUEST_xyz */
+
+	int64_t		displacement;		/* optional addr displacement */
+	int64_t		immediate;		/* optional immediate operand */
+
+	uint8_t		decoded;	/* set to 1 if successfully decoded */
+
+	struct vie_op	op;			/* opcode description */
+};
+
 enum vm_exitcode {
 	VM_EXITCODE_INOUT,
 	VM_EXITCODE_VMX,
@@ -355,14 +418,11 @@ struct vm_inout {
 
 struct vm_inout_str {
 	struct vm_inout	inout;		/* must be the first element */
-	enum vie_cpu_mode cpu_mode;
-	enum vie_paging_mode paging_mode;
+	struct vm_guest_paging paging;
 	uint64_t	rflags;
 	uint64_t	cr0;
-	uint64_t	cr3;
 	uint64_t	index;
 	uint64_t	count;		/* rep=1 (%rcx), rep=0 (1) */
-	int		cpl;
 	int		addrsize;
 	enum vm_reg_name seg_name;
 	struct seg_desc seg_desc;
@@ -384,10 +444,7 @@ struct vm_exit {
 		struct {
 			uint64_t	gpa;
 			uint64_t	gla;
-			uint64_t	cr3;
-			enum vie_cpu_mode cpu_mode;
-			enum vie_paging_mode paging_mode;
-			int		cpl;
+			struct vm_guest_paging paging;
 			struct vie	vie;
 		} inst_emul;
 		/*

Modified: head/sys/amd64/include/vmm_instruction_emul.h
==============================================================================
--- head/sys/amd64/include/vmm_instruction_emul.h	Sat May 24 19:13:25 2014	(r266626)
+++ head/sys/amd64/include/vmm_instruction_emul.h	Sat May 24 20:26:57 2014	(r266627)
@@ -29,66 +29,6 @@
 #ifndef	_VMM_INSTRUCTION_EMUL_H_
 #define	_VMM_INSTRUCTION_EMUL_H_
 
-enum vm_reg_name;
-
-enum vie_cpu_mode {
-	CPU_MODE_COMPATIBILITY,		/* IA-32E mode (CS.L = 0) */
-	CPU_MODE_64BIT,			/* IA-32E mode (CS.L = 1) */
-};
-
-enum vie_paging_mode {
-	PAGING_MODE_FLAT,
-	PAGING_MODE_32,
-	PAGING_MODE_PAE,
-	PAGING_MODE_64,
-};
-
-/*
- * The data structures 'vie' and 'vie_op' are meant to be opaque to the
- * consumers of instruction decoding. The only reason why their contents
- * need to be exposed is because they are part of the 'vm_exit' structure.
- */
-struct vie_op {
-	uint8_t		op_byte;	/* actual opcode byte */
-	uint8_t		op_type;	/* type of operation (e.g. MOV) */
-	uint16_t	op_flags;
-};
-
-#define	VIE_INST_SIZE	15
-struct vie {
-	uint8_t		inst[VIE_INST_SIZE];	/* instruction bytes */
-	uint8_t		num_valid;		/* size of the instruction */
-	uint8_t		num_processed;
-
-	uint8_t		rex_w:1,		/* REX prefix */
-			rex_r:1,
-			rex_x:1,
-			rex_b:1,
-			rex_present:1;
-
-	uint8_t		mod:2,			/* ModRM byte */
-			reg:4,
-			rm:4;
-
-	uint8_t		ss:2,			/* SIB byte */
-			index:4,
-			base:4;
-
-	uint8_t		disp_bytes;
-	uint8_t		imm_bytes;
-
-	uint8_t		scale;
-	int		base_register;		/* VM_REG_GUEST_xyz */
-	int		index_register;		/* VM_REG_GUEST_xyz */
-
-	int64_t		displacement;		/* optional addr displacement */
-	int64_t		immediate;		/* optional immediate operand */
-
-	uint8_t		decoded;	/* set to 1 if successfully decoded */
-
-	struct vie_op	op;			/* opcode description */
-};
-
 /*
  * Callback functions to read and write memory regions.
  */
@@ -122,6 +62,9 @@ int vie_update_register(void *vm, int vc
 int vie_alignment_check(int cpl, int operand_size, uint64_t cr0,
     uint64_t rflags, uint64_t gla);
 
+/* Returns 1 if the 'gla' is not canonical and 0 otherwise. */
+int vie_canonical_check(enum vm_cpu_mode cpu_mode, uint64_t gla);
+
 uint64_t vie_size2mask(int size);
 
 #ifdef _KERNEL
@@ -131,23 +74,22 @@ uint64_t vie_size2mask(int size);
  * 'vie' must be initialized before calling 'vmm_fetch_instruction()'
  */
 int vmm_fetch_instruction(struct vm *vm, int cpuid,
-			  uint64_t rip, int inst_length, uint64_t cr3,
-			  enum vie_paging_mode paging_mode, int cpl,
-			  struct vie *vie);
+			  struct vm_guest_paging *guest_paging,
+			  uint64_t rip, int inst_length, struct vie *vie);
 
 /*
  * Translate the guest linear address 'gla' to a guest physical address.
  *
  * Returns 0 on success and '*gpa' contains the result of the translation.
- * Returns 1 if a page fault exception was injected into the guest.
+ * Returns 1 if an exception was injected into the guest.
  * Returns -1 otherwise.
  */
-int vmm_gla2gpa(struct vm *vm, int vcpuid, uint64_t gla, uint64_t cr3,
-    uint64_t *gpa, enum vie_paging_mode paging_mode, int cpl, int prot);
+int vmm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
+    uint64_t gla, int prot, uint64_t *gpa);
 
 void vie_init(struct vie *vie);
 
-uint64_t vie_segbase(enum vm_reg_name segment, enum vie_cpu_mode cpu_mode,
+uint64_t vie_segbase(enum vm_reg_name segment, enum vm_cpu_mode cpu_mode,
     const struct seg_desc *desc);
 
 /*
@@ -163,7 +105,7 @@ uint64_t vie_segbase(enum vm_reg_name se
  */
 #define	VIE_INVALID_GLA		(1UL << 63)	/* a non-canonical address */
 int vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla,
-			   enum vie_cpu_mode cpu_mode, struct vie *vie);
+			   enum vm_cpu_mode cpu_mode, struct vie *vie);
 #endif	/* _KERNEL */
 
 #endif	/* _VMM_INSTRUCTION_EMUL_H_ */

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c	Sat May 24 19:13:25 2014	(r266626)
+++ head/sys/amd64/vmm/intel/vmx.c	Sat May 24 20:26:57 2014	(r266627)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/vmm.h>
 #include <machine/vmm_dev.h>
+#include <machine/vmm_instruction_emul.h>
 #include "vmm_host.h"
 #include "vmm_ioport.h"
 #include "vmm_ipi.h"
@@ -1517,7 +1518,7 @@ vmx_cpl(void)
 	return ((ssar >> 5) & 0x3);
 }
 
-static enum vie_cpu_mode
+static enum vm_cpu_mode
 vmx_cpu_mode(void)
 {
 
@@ -1527,7 +1528,7 @@ vmx_cpu_mode(void)
 		return (CPU_MODE_COMPATIBILITY);
 }
 
-static enum vie_paging_mode
+static enum vm_paging_mode
 vmx_paging_mode(void)
 {
 
@@ -1607,15 +1608,21 @@ inout_str_seginfo(struct vmx *vmx, int v
 }
 
 static void
+vmx_paging_info(struct vm_guest_paging *paging)
+{
+	paging->cr3 = vmcs_guest_cr3();
+	paging->cpl = vmx_cpl();
+	paging->cpu_mode = vmx_cpu_mode();
+	paging->paging_mode = vmx_paging_mode();
+}
+
+static void
 vmexit_inst_emul(struct vm_exit *vmexit, uint64_t gpa, uint64_t gla)
 {
 	vmexit->exitcode = VM_EXITCODE_INST_EMUL;
 	vmexit->u.inst_emul.gpa = gpa;
 	vmexit->u.inst_emul.gla = gla;
-	vmexit->u.inst_emul.cr3 = vmcs_guest_cr3();
-	vmexit->u.inst_emul.cpu_mode = vmx_cpu_mode();
-	vmexit->u.inst_emul.paging_mode = vmx_paging_mode();
-	vmexit->u.inst_emul.cpl = vmx_cpl();
+	vmx_paging_info(&vmexit->u.inst_emul.paging);
 }
 
 static int
@@ -1998,12 +2005,9 @@ vmx_exit_process(struct vmx *vmx, int vc
 			inst_info = vmcs_read(VMCS_EXIT_INSTRUCTION_INFO);
 			vmexit->exitcode = VM_EXITCODE_INOUT_STR;
 			vis = &vmexit->u.inout_str;
-			vis->cpu_mode = vmx_cpu_mode();
-			vis->paging_mode = vmx_paging_mode();
+			vmx_paging_info(&vis->paging);
 			vis->rflags = vmcs_read(VMCS_GUEST_RFLAGS);
 			vis->cr0 = vmcs_read(VMCS_GUEST_CR0);
-			vis->cr3 = vmcs_read(VMCS_GUEST_CR3);
-			vis->cpl = vmx_cpl();
 			vis->index = inout_str_index(vmx, vcpu, in);
 			vis->count = inout_str_count(vmx, vcpu, vis->inout.rep);
 			vis->addrsize = inout_str_addrsize(inst_info);

Modified: head/sys/amd64/vmm/vmm.c
==============================================================================
--- head/sys/amd64/vmm/vmm.c	Sat May 24 19:13:25 2014	(r266626)
+++ head/sys/amd64/vmm/vmm.c	Sat May 24 20:26:57 2014	(r266627)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/vmm.h>
 #include <machine/vmm_dev.h>
+#include <machine/vmm_instruction_emul.h>
 
 #include "vmm_ioport.h"
 #include "vmm_ktr.h"
@@ -1132,32 +1133,25 @@ vm_handle_inst_emul(struct vm *vm, int v
 	struct vie *vie;
 	struct vcpu *vcpu;
 	struct vm_exit *vme;
-	int cpl, error, inst_length;
-	uint64_t rip, gla, gpa, cr3;
-	enum vie_cpu_mode cpu_mode;
-	enum vie_paging_mode paging_mode;
+	uint64_t gla, gpa;
+	struct vm_guest_paging *paging;
 	mem_region_read_t mread;
 	mem_region_write_t mwrite;
+	int error;
 
 	vcpu = &vm->vcpu[vcpuid];
 	vme = &vcpu->exitinfo;
 
-	rip = vme->rip;
-	inst_length = vme->inst_length;
-
 	gla = vme->u.inst_emul.gla;
 	gpa = vme->u.inst_emul.gpa;
-	cr3 = vme->u.inst_emul.cr3;
-	cpl = vme->u.inst_emul.cpl;
-	cpu_mode = vme->u.inst_emul.cpu_mode;
-	paging_mode = vme->u.inst_emul.paging_mode;
 	vie = &vme->u.inst_emul.vie;
+	paging = &vme->u.inst_emul.paging;
 
 	vie_init(vie);
 
 	/* Fetch, decode and emulate the faulting instruction */
-	error = vmm_fetch_instruction(vm, vcpuid, rip, inst_length, cr3,
-	    paging_mode, cpl, vie);
+	error = vmm_fetch_instruction(vm, vcpuid, paging, vme->rip,
+	    vme->inst_length, vie);
 	if (error == 1)
 		return (0);		/* Resume guest to handle page fault */
 	else if (error == -1)
@@ -1165,7 +1159,7 @@ vm_handle_inst_emul(struct vm *vm, int v
 	else if (error != 0)
 		panic("%s: vmm_fetch_instruction error %d", __func__, error);
 
-	if (vmm_decode_instruction(vm, vcpuid, gla, cpu_mode, vie) != 0)
+	if (vmm_decode_instruction(vm, vcpuid, gla, paging->cpu_mode, vie) != 0)
 		return (EFAULT);
 
 	/* return to userland unless this is an in-kernel emulated device */

Modified: head/sys/amd64/vmm/vmm_instruction_emul.c
==============================================================================
--- head/sys/amd64/vmm/vmm_instruction_emul.c	Sat May 24 19:13:25 2014	(r266626)
+++ head/sys/amd64/vmm/vmm_instruction_emul.c	Sat May 24 20:26:57 2014	(r266627)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #define	KASSERT(exp,msg)	assert((exp))
 #endif	/* _KERNEL */
 
+#include <machine/vmm_instruction_emul.h>
 #include <x86/psl.h>
 #include <x86/specialreg.h>
 
@@ -579,6 +580,25 @@ vie_alignment_check(int cpl, int size, u
 	return ((gla & (size - 1)) ? 1 : 0);
 }
 
+int
+vie_canonical_check(enum vm_cpu_mode cpu_mode, uint64_t gla)
+{
+	uint64_t mask;
+
+	if (cpu_mode != CPU_MODE_64BIT)
+		return (0);
+
+	/*
+	 * The value of the bit 47 in the 'gla' should be replicated in the
+	 * most significant 16 bits.
+	 */
+	mask = ~((1UL << 48) - 1);
+	if (gla & (1UL << 47))
+		return ((gla & mask) != mask);
+	else
+		return ((gla & mask) != 0);
+}
+
 uint64_t
 vie_size2mask(int size)
 {
@@ -637,31 +657,41 @@ ptp_hold(struct vm *vm, vm_paddr_t ptpph
 }
 
 int
-vmm_gla2gpa(struct vm *vm, int vcpuid, uint64_t gla, uint64_t ptpphys,
-    uint64_t *gpa, enum vie_paging_mode paging_mode, int cpl, int prot)
+vmm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging,
+    uint64_t gla, int prot, uint64_t *gpa)
 {
 	int nlevels, pfcode, ptpshift, ptpindex, retval, usermode, writable;
 	u_int retries;
-	uint64_t *ptpbase, pte, pgsize;
+	uint64_t *ptpbase, ptpphys, pte, pgsize;
 	uint32_t *ptpbase32, pte32;
 	void *cookie;
 
-	usermode = (cpl == 3 ? 1 : 0);
+	usermode = (paging->cpl == 3 ? 1 : 0);
 	writable = prot & VM_PROT_WRITE;
 	cookie = NULL;
 	retval = 0;
 	retries = 0;
 restart:
+	ptpphys = paging->cr3;		/* root of the page tables */
 	ptp_release(&cookie);
 	if (retries++ > 0)
 		maybe_yield();
 
-	if (paging_mode == PAGING_MODE_FLAT) {
+	if (vie_canonical_check(paging->cpu_mode, gla)) {
+		/*
+		 * XXX assuming a non-stack reference otherwise a stack fault
+		 * should be generated.
+		 */
+		vm_inject_gp(vm, vcpuid);
+		goto fault;
+	}
+
+	if (paging->paging_mode == PAGING_MODE_FLAT) {
 		*gpa = gla;
 		goto done;
 	}
 
-	if (paging_mode == PAGING_MODE_32) {
+	if (paging->paging_mode == PAGING_MODE_32) {
 		nlevels = 2;
 		while (--nlevels >= 0) {
 			/* Zero out the lower 12 bits. */
@@ -684,7 +714,7 @@ restart:
 				pfcode = pf_error_code(usermode, prot, 0,
 				    pte32);
 				vm_inject_pf(vm, vcpuid, pfcode, gla);
-				goto pagefault;
+				goto fault;
 			}
 
 			/*
@@ -722,7 +752,7 @@ restart:
 		goto done;
 	}
 
-	if (paging_mode == PAGING_MODE_PAE) {
+	if (paging->paging_mode == PAGING_MODE_PAE) {
 		/* Zero out the lower 5 bits and the upper 32 bits */
 		ptpphys &= 0xffffffe0UL;
 
@@ -737,7 +767,7 @@ restart:
 		if ((pte & PG_V) == 0) {
 			pfcode = pf_error_code(usermode, prot, 0, pte);
 			vm_inject_pf(vm, vcpuid, pfcode, gla);
-			goto pagefault;
+			goto fault;
 		}
 
 		ptpphys = pte;
@@ -764,7 +794,7 @@ restart:
 		    (writable && (pte & PG_RW) == 0)) {
 			pfcode = pf_error_code(usermode, prot, 0, pte);
 			vm_inject_pf(vm, vcpuid, pfcode, gla);
-			goto pagefault;
+			goto fault;
 		}
 
 		/* Set the accessed bit in the page table entry */
@@ -779,7 +809,7 @@ restart:
 			if (pgsize > 1 * GB) {
 				pfcode = pf_error_code(usermode, prot, 1, pte);
 				vm_inject_pf(vm, vcpuid, pfcode, gla);
-				goto pagefault;
+				goto fault;
 			}
 			break;
 		}
@@ -802,15 +832,14 @@ done:
 error:
 	retval = -1;
 	goto done;
-pagefault:
+fault:
 	retval = 1;
 	goto done;
 }
 
 int
-vmm_fetch_instruction(struct vm *vm, int cpuid, uint64_t rip, int inst_length,
-		      uint64_t cr3, enum vie_paging_mode paging_mode, int cpl,
-		      struct vie *vie)
+vmm_fetch_instruction(struct vm *vm, int cpuid, struct vm_guest_paging *paging,
+    uint64_t rip, int inst_length, struct vie *vie)
 {
 	int n, error, prot;
 	uint64_t gpa, off;
@@ -826,8 +855,7 @@ vmm_fetch_instruction(struct vm *vm, int
 
 	/* Copy the instruction into 'vie' */
 	while (vie->num_valid < inst_length) {
-		error = vmm_gla2gpa(vm, cpuid, rip, cr3, &gpa, paging_mode,
-		    cpl, prot);
+		error = vmm_gla2gpa(vm, cpuid, paging, rip, prot, &gpa);
 		if (error)
 			return (error);
 
@@ -930,7 +958,7 @@ decode_opcode(struct vie *vie)
 }
 
 static int
-decode_modrm(struct vie *vie, enum vie_cpu_mode cpu_mode)
+decode_modrm(struct vie *vie, enum vm_cpu_mode cpu_mode)
 {
 	uint8_t x;
 
@@ -1210,7 +1238,7 @@ verify_gla(struct vm *vm, int cpuid, uin
 
 int
 vmm_decode_instruction(struct vm *vm, int cpuid, uint64_t gla,
-		       enum vie_cpu_mode cpu_mode, struct vie *vie)
+		       enum vm_cpu_mode cpu_mode, struct vie *vie)
 {
 
 	if (cpu_mode == CPU_MODE_64BIT) {
@@ -1245,7 +1273,7 @@ vmm_decode_instruction(struct vm *vm, in
 }
 
 uint64_t
-vie_segbase(enum vm_reg_name seg, enum vie_cpu_mode cpu_mode,
+vie_segbase(enum vm_reg_name seg, enum vm_cpu_mode cpu_mode,
     const struct seg_desc *desc)
 {
 	int basesize;

Modified: head/sys/amd64/vmm/vmm_ioport.c
==============================================================================
--- head/sys/amd64/vmm/vmm_ioport.c	Sat May 24 19:13:25 2014	(r266626)
+++ head/sys/amd64/vmm/vmm_ioport.c	Sat May 24 20:26:57 2014	(r266627)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm.h>
 
 #include <machine/vmm.h>
+#include <machine/vmm_instruction_emul.h>
 #include <x86/psl.h>
 
 #include "vatpic.h"
@@ -167,9 +168,9 @@ emulate_inout_str(struct vm *vm, int vcp
 	 * The #GP(0) fault conditions described above don't apply in
 	 * 64-bit mode.
 	 */
-	if (vis->cpu_mode != CPU_MODE_64BIT) { 
+	if (vis->paging.cpu_mode != CPU_MODE_64BIT) { 
 		VCPU_CTR1(vm, vcpuid, "ins/outs not emulated in cpu mode %d",
-		    vis->cpu_mode);
+		    vis->paging.cpu_mode);
 		return (EINVAL);
 	}
 
@@ -181,7 +182,8 @@ emulate_inout_str(struct vm *vm, int vcp
 		return (EINVAL);
 	}
 
-	segbase = vie_segbase(vis->seg_name, vis->cpu_mode, &vis->seg_desc);
+	segbase = vie_segbase(vis->seg_name, vis->paging.cpu_mode,
+	    &vis->seg_desc);
 	index = vis->index & vie_size2mask(vis->addrsize);
 	gla = segbase + index;
 
@@ -195,8 +197,8 @@ emulate_inout_str(struct vm *vm, int vcp
 	}
 	vis->gla = gla;
 
-	error = vmm_gla2gpa(vm, vcpuid, gla, vis->cr3, &vis->gpa,
-	    vis->paging_mode, vis->cpl, in ? VM_PROT_WRITE : VM_PROT_READ);
+	error = vmm_gla2gpa(vm, vcpuid, &vis->paging, gla,
+	    in ? VM_PROT_WRITE : VM_PROT_READ, &vis->gpa);
 	KASSERT(error == 0 || error == 1 || error == -1,
 	    ("%s: vmm_gla2gpa unexpected error %d", __func__, error));
 	if (error == -1) {

Modified: head/usr.sbin/bhyve/inout.c
==============================================================================
--- head/usr.sbin/bhyve/inout.c	Sat May 24 19:13:25 2014	(r266626)
+++ head/usr.sbin/bhyve/inout.c	Sat May 24 20:26:57 2014	(r266627)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <x86/segments.h>
 
 #include <machine/vmm.h>
+#include <machine/vmm_instruction_emul.h>
 #include <vmmapi.h>
 
 #include <stdio.h>
@@ -152,7 +153,7 @@ emulate_inout(struct vmctx *ctx, int vcp
 		gpaend = rounddown(gpa + PAGE_SIZE, PAGE_SIZE);
 		gva = paddr_guest2host(ctx, gpa, gpaend - gpa);
 
-		if (vie_alignment_check(vis->cpl, bytes, vis->cr0,
+		if (vie_alignment_check(vis->paging.cpl, bytes, vis->cr0,
 		    vis->rflags, vis->gla)) {
 			error = vm_inject_exception2(ctx, vcpu, IDT_AC, 0);
 			assert(error == 0);

Modified: head/usr.sbin/bhyve/mem.c
==============================================================================
--- head/usr.sbin/bhyve/mem.c	Sat May 24 19:13:25 2014	(r266626)
+++ head/usr.sbin/bhyve/mem.c	Sat May 24 20:26:57 2014	(r266627)
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/tree.h>
 #include <sys/errno.h>
 #include <machine/vmm.h>
+#include <machine/vmm_instruction_emul.h>
 
 #include <stdio.h>
 #include <stdlib.h>



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