svn commit: r280447 - in head/sys/amd64: include vmm vmm/amd vmm/intel

Tycho Nightingale tychon at FreeBSD.org
Tue Mar 24 17:12:38 UTC 2015


Author: tychon
Date: Tue Mar 24 17:12:36 2015
New Revision: 280447
URL: https://svnweb.freebsd.org/changeset/base/280447

Log:
  When fetching an instruction in non-64bit mode, consider the value of the
  code segment base address.
  
  Also if an instruction doesn't support a mod R/M (modRM) byte, don't
  be concerned if the CPU is in real mode.
  
  Reviewed by:	neel

Modified:
  head/sys/amd64/include/vmm.h
  head/sys/amd64/vmm/amd/svm.c
  head/sys/amd64/vmm/intel/vmx.c
  head/sys/amd64/vmm/vmm.c
  head/sys/amd64/vmm/vmm_instruction_emul.c

Modified: head/sys/amd64/include/vmm.h
==============================================================================
--- head/sys/amd64/include/vmm.h	Tue Mar 24 16:53:16 2015	(r280446)
+++ head/sys/amd64/include/vmm.h	Tue Mar 24 17:12:36 2015	(r280447)
@@ -551,6 +551,7 @@ struct vm_exit {
 		struct {
 			uint64_t	gpa;
 			uint64_t	gla;
+			uint64_t	cs_base;
 			int		cs_d;		/* CS.D */
 			struct vm_guest_paging paging;
 			struct vie	vie;

Modified: head/sys/amd64/vmm/amd/svm.c
==============================================================================
--- head/sys/amd64/vmm/amd/svm.c	Tue Mar 24 16:53:16 2015	(r280446)
+++ head/sys/amd64/vmm/amd/svm.c	Tue Mar 24 17:12:36 2015	(r280447)
@@ -799,8 +799,13 @@ svm_handle_inst_emul(struct vmcb *vmcb, 
 	KASSERT(error == 0, ("%s: vmcb_seg(CS) error %d", __func__, error));
 
 	switch(paging->cpu_mode) {
+	case CPU_MODE_REAL:
+		vmexit->u.inst_emul.cs_base = seg.base;
+		vmexit->u.inst_emul.cs_d = 0;
 	case CPU_MODE_PROTECTED:
 	case CPU_MODE_COMPATIBILITY:
+		vmexit->u.inst_emul.cs_base = seg.base;
+
 		/*
 		 * Section 4.8.1 of APM2, Default Operand Size or D bit.
 		 */
@@ -808,6 +813,7 @@ svm_handle_inst_emul(struct vmcb *vmcb, 
 		    1 : 0;
 		break;
 	default:
+		vmexit->u.inst_emul.cs_base = 0;
 		vmexit->u.inst_emul.cs_d = 0;
 		break;	
 	}

Modified: head/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- head/sys/amd64/vmm/intel/vmx.c	Tue Mar 24 16:53:16 2015	(r280446)
+++ head/sys/amd64/vmm/intel/vmx.c	Tue Mar 24 17:12:36 2015	(r280447)
@@ -1784,12 +1784,18 @@ vmexit_inst_emul(struct vm_exit *vmexit,
 	vmexit->u.inst_emul.gla = gla;
 	vmx_paging_info(paging);
 	switch (paging->cpu_mode) {
+	case CPU_MODE_REAL:
+		vmexit->u.inst_emul.cs_base = vmcs_read(VMCS_GUEST_CS_BASE);
+		vmexit->u.inst_emul.cs_d = 0;
+		break;
 	case CPU_MODE_PROTECTED:
 	case CPU_MODE_COMPATIBILITY:
+		vmexit->u.inst_emul.cs_base = vmcs_read(VMCS_GUEST_CS_BASE);
 		csar = vmcs_read(VMCS_GUEST_CS_ACCESS_RIGHTS);
 		vmexit->u.inst_emul.cs_d = SEG_DESC_DEF32(csar);
 		break;
 	default:
+		vmexit->u.inst_emul.cs_base = 0;
 		vmexit->u.inst_emul.cs_d = 0;
 		break;
 	}

Modified: head/sys/amd64/vmm/vmm.c
==============================================================================
--- head/sys/amd64/vmm/vmm.c	Tue Mar 24 16:53:16 2015	(r280446)
+++ head/sys/amd64/vmm/vmm.c	Tue Mar 24 17:12:36 2015	(r280447)
@@ -1251,7 +1251,7 @@ vm_handle_inst_emul(struct vm *vm, int v
 	struct vie *vie;
 	struct vcpu *vcpu;
 	struct vm_exit *vme;
-	uint64_t gla, gpa;
+	uint64_t gla, gpa, cs_base;
 	struct vm_guest_paging *paging;
 	mem_region_read_t mread;
 	mem_region_write_t mwrite;
@@ -1263,6 +1263,7 @@ vm_handle_inst_emul(struct vm *vm, int v
 
 	gla = vme->u.inst_emul.gla;
 	gpa = vme->u.inst_emul.gpa;
+	cs_base = vme->u.inst_emul.cs_base;
 	cs_d = vme->u.inst_emul.cs_d;
 	vie = &vme->u.inst_emul.vie;
 	paging = &vme->u.inst_emul.paging;
@@ -1277,8 +1278,8 @@ vm_handle_inst_emul(struct vm *vm, int v
 		 * maximum size instruction.
 		 */
 		length = vme->inst_length ? vme->inst_length : VIE_INST_SIZE;
-		error = vmm_fetch_instruction(vm, vcpuid, paging, vme->rip,
-		    length, vie);
+		error = vmm_fetch_instruction(vm, vcpuid, paging, vme->rip +
+		    cs_base, length, vie);
 	} else {
 		/*
 		 * The instruction bytes have already been copied into 'vie'

Modified: head/sys/amd64/vmm/vmm_instruction_emul.c
==============================================================================
--- head/sys/amd64/vmm/vmm_instruction_emul.c	Tue Mar 24 16:53:16 2015	(r280446)
+++ head/sys/amd64/vmm/vmm_instruction_emul.c	Tue Mar 24 17:12:36 2015	(r280447)
@@ -1825,12 +1825,12 @@ decode_modrm(struct vie *vie, enum vm_cp
 {
 	uint8_t x;
 
-	if (cpu_mode == CPU_MODE_REAL)
-		return (-1);
-
 	if (vie->op.op_flags & VIE_OP_F_NO_MODRM)
 		return (0);
 
+	if (cpu_mode == CPU_MODE_REAL)
+		return (-1);
+
 	if (vie_peek(vie, &x))
 		return (-1);
 


More information about the svn-src-all mailing list