svn commit: r283293 - in head/sys/amd64/vmm: . intel

Neel Natu neel at FreeBSD.org
Fri May 22 17:34:24 UTC 2015


Author: neel
Date: Fri May 22 17:34:22 2015
New Revision: 283293
URL: https://svnweb.freebsd.org/changeset/base/283293

Log:
  Don't rely on the 'VM-exit instruction length' field in the VMCS to always
  have an accurate length on an EPT violation. This is not needed by the
  instruction decoding code because it also has to work with AMD/SVM that
  does not provide a valid instruction length on a Nested Page Fault.
  
  In collaboration with:	Leon Dang (ldang at nahannisys.com)
  Discussed with:		grehan
  MFC after:		1 week

Modified:
  head/sys/amd64/vmm/intel/vmx.c
  head/sys/amd64/vmm/vmm.c

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c	Fri May 22 17:06:33 2015	(r283292)
+++ head/sys/amd64/vmm/intel/vmx.c	Fri May 22 17:34:22 2015	(r283293)
@@ -1780,6 +1780,7 @@ vmexit_inst_emul(struct vm_exit *vmexit,
 	paging = &vmexit->u.inst_emul.paging;
 
 	vmexit->exitcode = VM_EXITCODE_INST_EMUL;
+	vmexit->inst_length = 0;
 	vmexit->u.inst_emul.gpa = gpa;
 	vmexit->u.inst_emul.gla = gla;
 	vmx_paging_info(paging);

Modified: head/sys/amd64/vmm/vmm.c
==============================================================================
--- head/sys/amd64/vmm/vmm.c	Fri May 22 17:06:33 2015	(r283292)
+++ head/sys/amd64/vmm/vmm.c	Fri May 22 17:34:22 2015	(r283293)
@@ -1256,11 +1256,14 @@ vm_handle_inst_emul(struct vm *vm, int v
 	mem_region_read_t mread;
 	mem_region_write_t mwrite;
 	enum vm_cpu_mode cpu_mode;
-	int cs_d, error, fault, length;
+	int cs_d, error, fault;
 
 	vcpu = &vm->vcpu[vcpuid];
 	vme = &vcpu->exitinfo;
 
+	KASSERT(vme->inst_length == 0, ("%s: invalid inst_length %d",
+	    __func__, vme->inst_length));
+
 	gla = vme->u.inst_emul.gla;
 	gpa = vme->u.inst_emul.gpa;
 	cs_base = vme->u.inst_emul.cs_base;
@@ -1273,13 +1276,8 @@ vm_handle_inst_emul(struct vm *vm, int v
 
 	/* Fetch, decode and emulate the faulting instruction */
 	if (vie->num_valid == 0) {
-		/*
-		 * If the instruction length is not known then assume a
-		 * maximum size instruction.
-		 */
-		length = vme->inst_length ? vme->inst_length : VIE_INST_SIZE;
 		error = vmm_fetch_instruction(vm, vcpuid, paging, vme->rip +
-		    cs_base, length, vie, &fault);
+		    cs_base, VIE_INST_SIZE, vie, &fault);
 	} else {
 		/*
 		 * The instruction bytes have already been copied into 'vie'
@@ -1297,13 +1295,12 @@ vm_handle_inst_emul(struct vm *vm, int v
 	}
 
 	/*
-	 * If the instruction length was not specified then update it now
-	 * along with 'nextrip'.
+	 * Update 'nextrip' based on the length of the emulated instruction.
 	 */
-	if (vme->inst_length == 0) {
-		vme->inst_length = vie->num_processed;
-		vcpu->nextrip += vie->num_processed;
-	}
+	vme->inst_length = vie->num_processed;
+	vcpu->nextrip += vie->num_processed;
+	VCPU_CTR1(vm, vcpuid, "nextrip updated to %#lx after instruction "
+	    "decoding", vcpu->nextrip);
  
 	/* return to userland unless this is an in-kernel emulated device */
 	if (gpa >= DEFAULT_APIC_BASE && gpa < DEFAULT_APIC_BASE + PAGE_SIZE) {


More information about the svn-src-head mailing list