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