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);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to