summaryrefslogtreecommitdiff
path: root/src/recompiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/recompiler')
-rw-r--r--src/recompiler/Makefile.kmk12
-rw-r--r--src/recompiler/Sun/config-host.h2
-rw-r--r--src/recompiler/Sun/config.h2
-rw-r--r--src/recompiler/Sun/crt/stdio.h2
-rw-r--r--src/recompiler/Sun/deftoimp.sed2
-rw-r--r--src/recompiler/VBoxREM.def2
-rw-r--r--src/recompiler/VBoxREMWrapper.cpp36
-rw-r--r--src/recompiler/VBoxREMWrapperA.asm2
-rw-r--r--src/recompiler/VBoxRecompiler.c458
-rw-r--r--src/recompiler/cpu-defs.h2
-rw-r--r--src/recompiler/cpu-exec.c10
-rw-r--r--src/recompiler/exec.c2
-rw-r--r--src/recompiler/target-i386/cpu.h38
-rw-r--r--src/recompiler/target-i386/op_helper.c226
-rw-r--r--src/recompiler/target-i386/translate.c2
15 files changed, 500 insertions, 298 deletions
diff --git a/src/recompiler/Makefile.kmk b/src/recompiler/Makefile.kmk
index 79f8d2b9..3104870f 100644
--- a/src/recompiler/Makefile.kmk
+++ b/src/recompiler/Makefile.kmk
@@ -70,6 +70,12 @@ VBoxRemPrimary_DEFS += IN_REM_R3 REM_INCLUDE_CPU_H NEED_CPU_H
ifdef IEM_VERIFICATION_MODE
VBoxRemPrimary_DEFS += IEM_VERIFICATION_MODE
endif
+ifdef VBOX_WITH_RAW_MODE
+ VBoxRemPrimary_DEFS += VBOX_WITH_RAW_MODE
+endif
+ifdef VBOX_WITH_RAW_RING1
+ VBoxRemPrimary_DEFS += VBOX_WITH_RAW_RING1
+endif
VBoxRemPrimary_DEFS.linux = _GNU_SOURCE
ifdef VBOX_SOLARIS_10
VBoxRemPrimary_DEFS.solaris = CONFIG_SOLARIS_VERSION=10
@@ -197,9 +203,13 @@ else
# GNU ld (rubenvb-4.5.4) 2.22.52.20120716 doesn't fix up rip relative
# addressing in the import libraries generated by microsoft link.exe. So, we
# have to regenerate these.
+ # Note! The chdir to the output directory is because dlltool writes temporary files to the current directory.
$$(VBoxRemPrimary_0_OUTDIR)/VBoxVMMImp.a \
$$(VBoxRemPrimary_0_OUTDIR)/VBoxRTImp.a : $$(VBoxRemPrimary_0_OUTDIR)/$$(notdir $$(basename $$@)).def
- $(TOOL_MINGWW64_DLLTOOL) --output-lib "$@" --input-def "$<" --dllname "$(patsubst %Imp.a,%.dll,$(notdir $@))"
+ $(REDIRECT) -C "$(dir $@)" -- $(TOOL_MINGWW64_DLLTOOL) \
+ --output-lib "$@" \
+ --input-def "$<" \
+ --dllname "$(patsubst %Imp.a,%.dll,$(notdir $@))"
$$(VBoxRemPrimary_0_OUTDIR)/VBoxVMMImp.def \
$$(VBoxRemPrimary_0_OUTDIR)/VBoxRTImp.def : \
diff --git a/src/recompiler/Sun/config-host.h b/src/recompiler/Sun/config-host.h
index 6768e947..7091bdf6 100644
--- a/src/recompiler/Sun/config-host.h
+++ b/src/recompiler/Sun/config-host.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/recompiler/Sun/config.h b/src/recompiler/Sun/config.h
index 79276c59..cd4f4f91 100644
--- a/src/recompiler/Sun/config.h
+++ b/src/recompiler/Sun/config.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/recompiler/Sun/crt/stdio.h b/src/recompiler/Sun/crt/stdio.h
index ae14a4a1..35f93261 100644
--- a/src/recompiler/Sun/crt/stdio.h
+++ b/src/recompiler/Sun/crt/stdio.h
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/recompiler/Sun/deftoimp.sed b/src/recompiler/Sun/deftoimp.sed
index 089a0d99..4c7557f7 100644
--- a/src/recompiler/Sun/deftoimp.sed
+++ b/src/recompiler/Sun/deftoimp.sed
@@ -5,7 +5,7 @@
#
#
-# Copyright (C) 2006-2007 Oracle Corporation
+# Copyright (C) 2006-2010 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
diff --git a/src/recompiler/VBoxREM.def b/src/recompiler/VBoxREM.def
index 3d6d07b9..d87690fb 100644
--- a/src/recompiler/VBoxREM.def
+++ b/src/recompiler/VBoxREM.def
@@ -4,7 +4,7 @@
;
;
-; Copyright (C) 2006-2007 Oracle Corporation
+; Copyright (C) 2006-2011 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
diff --git a/src/recompiler/VBoxREMWrapper.cpp b/src/recompiler/VBoxREMWrapper.cpp
index e27674dd..db613327 100644
--- a/src/recompiler/VBoxREMWrapper.cpp
+++ b/src/recompiler/VBoxREMWrapper.cpp
@@ -4,7 +4,7 @@
* VBoxREM Win64 DLL Wrapper.
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -204,7 +204,7 @@
#include <VBox/vmm/mm.h>
#include <VBox/vmm/em.h>
#include <VBox/vmm/ssm.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
#include <VBox/vmm/patm.h>
#include <VBox/vmm/pdm.h>
#include <VBox/vmm/pdmcritsect.h>
@@ -614,7 +614,7 @@ static const REMPARMDESC g_aArgsDBGCRegisterCommands[] =
# endif
static const REMPARMDESC g_aArgsDBGFR3DisasInstrEx[] =
{
- { REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(PUVM), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(VMCPUID), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(RTSEL), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(RTGCPTR), NULL },
@@ -630,23 +630,24 @@ static const REMPARMDESC g_aArgsDBGFR3DisasInstrCurrentLogInternal[] =
};
static const REMPARMDESC g_aArgsDBGFR3Info[] =
{
- { REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(PUVM), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(const char *), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(const char *), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(PCDBGFINFOHLP), NULL }
};
static const REMPARMDESC g_aArgsDBGFR3AsSymbolByAddr[] =
{
- { REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(PUVM), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(RTDBGAS), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(PCDBGFADDRESS), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL },
{ REMPARMDESC_FLAGS_GCPTR, sizeof(PRTGCINTPTR), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(PRTDBGSYMBOL), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(PRTDBGMOD), NULL }
};
static const REMPARMDESC g_aArgsDBGFR3AddrFromFlat[] =
{
- { REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(PUVM), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(PDBGFADDRESS), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(RTGCUINTPTR), NULL }
};
@@ -669,7 +670,7 @@ static const REMPARMDESC g_aArgsEMSetInhibitInterruptsPC[] =
{ REMPARMDESC_FLAGS_INT, sizeof(PVMCPU), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(RTGCPTR), NULL }
};
-static const REMPARMDESC g_aArgsHWACCMR3CanExecuteGuest[] =
+static const REMPARMDESC g_aArgsHMR3CanExecuteGuest[] =
{
{ REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL },
@@ -679,6 +680,7 @@ static const REMPARMDESC g_aArgsHWACCMR3CanExecuteGuest[] =
static const REMPARMDESC g_aArgsIOMIOPortRead[] =
{
{ REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(PVMCPU), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(RTIOPORT), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t *), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL }
@@ -686,6 +688,7 @@ static const REMPARMDESC g_aArgsIOMIOPortRead[] =
static const REMPARMDESC g_aArgsIOMIOPortWrite[] =
{
{ REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(PVMCPU), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(RTIOPORT), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL }
@@ -693,6 +696,7 @@ static const REMPARMDESC g_aArgsIOMIOPortWrite[] =
static const REMPARMDESC g_aArgsIOMMMIORead[] =
{
{ REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(PVMCPU), NULL },
{ REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t *), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL }
@@ -700,6 +704,7 @@ static const REMPARMDESC g_aArgsIOMMMIORead[] =
static const REMPARMDESC g_aArgsIOMMMIOWrite[] =
{
{ REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(PVMCPU), NULL },
{ REMPARMDESC_FLAGS_GCPHYS, sizeof(RTGCPHYS), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint32_t), NULL }
@@ -727,11 +732,6 @@ static const REMPARMDESC g_aArgsPATMR3QueryOpcode[] =
{ REMPARMDESC_FLAGS_INT, sizeof(RTRCPTR), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint8_t *), NULL }
};
-static const REMPARMDESC g_aArgsPATMR3QueryPatchMem[] =
-{
- { REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
- { REMPARMDESC_FLAGS_INT, sizeof(uint32_t *), NULL }
-};
static const REMPARMDESC g_aArgsPDMApicGetBase[] =
{
{ REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
@@ -741,6 +741,7 @@ static const REMPARMDESC g_aArgsPDMApicGetTPR[] =
{
{ REMPARMDESC_FLAGS_INT, sizeof(PVMCPU), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint8_t *), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(uint8_t *), NULL },
{ REMPARMDESC_FLAGS_INT, sizeof(uint8_t *), NULL }
};
static const REMPARMDESC g_aArgsPDMApicSetBase[] =
@@ -1019,7 +1020,7 @@ static const REMPARMDESC g_aArgsSTAMR3Register[] =
static const REMPARMDESC g_aArgsSTAMR3Deregister[] =
{
{ REMPARMDESC_FLAGS_INT, sizeof(PVM), NULL },
- { REMPARMDESC_FLAGS_INT, sizeof(void *), NULL },
+ { REMPARMDESC_FLAGS_INT, sizeof(const char *), NULL },
};
static const REMPARMDESC g_aArgsTRPMAssertTrap[] =
{
@@ -1238,7 +1239,8 @@ static REMFNDESC g_aVMMImports[] =
{ "EMRemIsLockOwner", VMM_FN(EMRemIsLockOwner), &g_aArgsVM[0], RT_ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_VOID, sizeof(bool), NULL },
{ "EMGetInhibitInterruptsPC", VMM_FN(EMGetInhibitInterruptsPC), &g_aArgsVMCPU[0], RT_ELEMENTS(g_aArgsVMCPU), REMFNDESC_FLAGS_RET_INT, sizeof(RTGCPTR), NULL },
{ "EMSetInhibitInterruptsPC", VMM_FN(EMSetInhibitInterruptsPC), &g_aArgsEMSetInhibitInterruptsPC[0], RT_ELEMENTS(g_aArgsEMSetInhibitInterruptsPC), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
- { "HWACCMR3CanExecuteGuest", VMM_FN(HWACCMR3CanExecuteGuest), &g_aArgsHWACCMR3CanExecuteGuest[0], RT_ELEMENTS(g_aArgsHWACCMR3CanExecuteGuest), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
+ { "HMIsEnabledNotMacro", VMM_FN(HMIsEnabledNotMacro), &g_aArgsVM[0], RT_ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
+ { "HMR3CanExecuteGuest", VMM_FN(HMR3CanExecuteGuest), &g_aArgsHMR3CanExecuteGuest[0], RT_ELEMENTS(g_aArgsHMR3CanExecuteGuest), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
{ "IOMIOPortRead", VMM_FN(IOMIOPortRead), &g_aArgsIOMIOPortRead[0], RT_ELEMENTS(g_aArgsIOMIOPortRead), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
{ "IOMIOPortWrite", VMM_FN(IOMIOPortWrite), &g_aArgsIOMIOPortWrite[0], RT_ELEMENTS(g_aArgsIOMIOPortWrite), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
{ "IOMMMIORead", VMM_FN(IOMMMIORead), &g_aArgsIOMMMIORead[0], RT_ELEMENTS(g_aArgsIOMMMIORead), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
@@ -1248,8 +1250,6 @@ static REMFNDESC g_aVMMImports[] =
{ "MMR3PhysGetRamSize", VMM_FN(MMR3PhysGetRamSize), &g_aArgsVM[0], RT_ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(uint64_t), NULL },
{ "PATMIsPatchGCAddr", VMM_FN(PATMIsPatchGCAddr), &g_aArgsPATMIsPatchGCAddr[0], RT_ELEMENTS(g_aArgsPATMIsPatchGCAddr), REMFNDESC_FLAGS_RET_INT, sizeof(bool), NULL },
{ "PATMR3QueryOpcode", VMM_FN(PATMR3QueryOpcode), &g_aArgsPATMR3QueryOpcode[0], RT_ELEMENTS(g_aArgsPATMR3QueryOpcode), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
- { "PATMR3QueryPatchMemGC", VMM_FN(PATMR3QueryPatchMemGC), &g_aArgsPATMR3QueryPatchMem[0], RT_ELEMENTS(g_aArgsPATMR3QueryPatchMem), REMFNDESC_FLAGS_RET_INT, sizeof(RTGCPTR), NULL },
- { "PATMR3QueryPatchMemHC", VMM_FN(PATMR3QueryPatchMemHC), &g_aArgsPATMR3QueryPatchMem[0], RT_ELEMENTS(g_aArgsPATMR3QueryPatchMem), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
{ "PDMApicGetBase", VMM_FN(PDMApicGetBase), &g_aArgsPDMApicGetBase[0], RT_ELEMENTS(g_aArgsPDMApicGetBase), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
{ "PDMApicGetTPR", VMM_FN(PDMApicGetTPR), &g_aArgsPDMApicGetTPR[0], RT_ELEMENTS(g_aArgsPDMApicGetTPR), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
{ "PDMApicSetBase", VMM_FN(PDMApicSetBase), &g_aArgsPDMApicSetBase[0], RT_ELEMENTS(g_aArgsPDMApicSetBase), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
@@ -1273,6 +1273,7 @@ static REMFNDESC g_aVMMImports[] =
{ "PGMPhysWrite", VMM_FN(PGMPhysWrite), &g_aArgsPGMPhysWrite[0], RT_ELEMENTS(g_aArgsPGMPhysWrite), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
{ "PGMChangeMode", VMM_FN(PGMChangeMode), &g_aArgsPGMChangeMode[0], RT_ELEMENTS(g_aArgsPGMChangeMode), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
{ "PGMFlushTLB", VMM_FN(PGMFlushTLB), &g_aArgsPGMFlushTLB[0], RT_ELEMENTS(g_aArgsPGMFlushTLB), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
+ { "PGMCr0WpEnabled", VMM_FN(PGMCr0WpEnabled), &g_aArgsVMCPU[0], RT_ELEMENTS(g_aArgsVMCPU), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
{ "PGMR3PhysReadU8", VMM_FN(PGMR3PhysReadU8), &g_aArgsPGMR3PhysReadUxx[0], RT_ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint8_t), NULL },
{ "PGMR3PhysReadU16", VMM_FN(PGMR3PhysReadU16), &g_aArgsPGMR3PhysReadUxx[0], RT_ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint16_t), NULL },
{ "PGMR3PhysReadU32", VMM_FN(PGMR3PhysReadU32), &g_aArgsPGMR3PhysReadUxx[0], RT_ELEMENTS(g_aArgsPGMR3PhysReadUxx), REMFNDESC_FLAGS_RET_INT, sizeof(uint32_t), NULL },
@@ -1309,11 +1310,8 @@ static REMFNDESC g_aVMMImports[] =
{ "TRPMSetErrorCode", VMM_FN(TRPMSetErrorCode), &g_aArgsTRPMSetErrorCode[0], RT_ELEMENTS(g_aArgsTRPMSetErrorCode), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
{ "TRPMSetFaultAddress", VMM_FN(TRPMSetFaultAddress), &g_aArgsTRPMSetFaultAddress[0], RT_ELEMENTS(g_aArgsTRPMSetFaultAddress), REMFNDESC_FLAGS_RET_VOID, 0, NULL },
{ "VMMGetCpu", VMM_FN(VMMGetCpu), &g_aArgsVM[0], RT_ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(PVMCPU), NULL },
- { "VMR3ReqCallWait", VMM_FN(VMR3ReqCallWait), &g_aArgsVMR3ReqCallWait[0], RT_ELEMENTS(g_aArgsVMR3ReqCallWait), REMFNDESC_FLAGS_RET_INT | REMFNDESC_FLAGS_ELLIPSIS, sizeof(int), NULL },
{ "VMR3ReqPriorityCallWait", VMM_FN(VMR3ReqPriorityCallWait), &g_aArgsVMR3ReqCallWait[0], RT_ELEMENTS(g_aArgsVMR3ReqCallWait), REMFNDESC_FLAGS_RET_INT | REMFNDESC_FLAGS_ELLIPSIS, sizeof(int), NULL },
{ "VMR3ReqFree", VMM_FN(VMR3ReqFree), &g_aArgsVMR3ReqFree[0], RT_ELEMENTS(g_aArgsVMR3ReqFree), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
- { "VMR3GetVMCPUId", VMM_FN(VMR3GetVMCPUId), &g_aArgsVM[0], RT_ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
- { "VMR3GetVMCPUNativeThread", VMM_FN(VMR3GetVMCPUNativeThread), &g_aArgsVM[0], RT_ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(void *), NULL },
// { "", VMM_FN(), &g_aArgsVM[0], RT_ELEMENTS(g_aArgsVM), REMFNDESC_FLAGS_RET_INT, sizeof(int), NULL },
};
diff --git a/src/recompiler/VBoxREMWrapperA.asm b/src/recompiler/VBoxREMWrapperA.asm
index ba7cc770..6b2c817e 100644
--- a/src/recompiler/VBoxREMWrapperA.asm
+++ b/src/recompiler/VBoxREMWrapperA.asm
@@ -4,7 +4,7 @@
;
;
-; Copyright (C) 2006-2007 Oracle Corporation
+; Copyright (C) 2006-2010 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
diff --git a/src/recompiler/VBoxRecompiler.c b/src/recompiler/VBoxRecompiler.c
index 5fe8e7b0..d74eeb0a 100644
--- a/src/recompiler/VBoxRecompiler.c
+++ b/src/recompiler/VBoxRecompiler.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -39,11 +39,12 @@
#include <VBox/vmm/pdm.h>
#include <VBox/vmm/dbgf.h>
#include <VBox/dbg.h>
-#include <VBox/vmm/hwaccm.h>
+#include <VBox/vmm/hm.h>
#include <VBox/vmm/patm.h>
#include <VBox/vmm/csam.h>
#include "REMInternal.h"
#include <VBox/vmm/vm.h>
+#include <VBox/vmm/uvm.h>
#include <VBox/param.h>
#include <VBox/err.h>
@@ -83,6 +84,14 @@ ram_addr_t get_phys_page_offset(target_ulong addr);
#define REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
+/** Selector flag shift between qemu and VBox.
+ * VBox shifts the qemu bits to the right. */
+#define SEL_FLAGS_SHIFT (8)
+/** Mask applied to the shifted qemu selector flags to get the attributes VBox
+ * (VT-x) needs. */
+#define SEL_FLAGS_SMASK UINT32_C(0x1F0FF)
+
+
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
@@ -91,12 +100,12 @@ static DECLCALLBACK(int) remR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion,
static void remR3StateUpdate(PVM pVM, PVMCPU pVCpu);
static int remR3InitPhysRamSizeAndDirtyMap(PVM pVM, bool fGuarded);
-static uint32_t remR3MMIOReadU8(void *pvVM, target_phys_addr_t GCPhys);
-static uint32_t remR3MMIOReadU16(void *pvVM, target_phys_addr_t GCPhys);
-static uint32_t remR3MMIOReadU32(void *pvVM, target_phys_addr_t GCPhys);
-static void remR3MMIOWriteU8(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32);
-static void remR3MMIOWriteU16(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32);
-static void remR3MMIOWriteU32(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32);
+static uint32_t remR3MMIOReadU8(void *pvEnv, target_phys_addr_t GCPhys);
+static uint32_t remR3MMIOReadU16(void *pvEnv, target_phys_addr_t GCPhys);
+static uint32_t remR3MMIOReadU32(void *pvEnv, target_phys_addr_t GCPhys);
+static void remR3MMIOWriteU8(void *pvEnv, target_phys_addr_t GCPhys, uint32_t u32);
+static void remR3MMIOWriteU16(void *pvEnv, target_phys_addr_t GCPhys, uint32_t u32);
+static void remR3MMIOWriteU32(void *pvEnv, target_phys_addr_t GCPhys, uint32_t u32);
static uint32_t remR3HandlerReadU8(void *pvVM, target_phys_addr_t GCPhys);
static uint32_t remR3HandlerReadU16(void *pvVM, target_phys_addr_t GCPhys);
@@ -192,7 +201,7 @@ CPUWriteMemoryFunc *g_apfnHandlerWrite[3] =
/*
* Debugger commands.
*/
-static DECLCALLBACK(int) remR3CmdDisasEnableStepping(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+static FNDBGCCMD remR3CmdDisasEnableStepping;;
/** '.remstep' arguments. */
static const DBGCVARDESC g_aArgRemStep[] =
@@ -332,7 +341,7 @@ REMR3DECL(int) REMR3Init(PVM pVM)
/*
* Register ram types.
*/
- pVM->rem.s.iMMIOMemType = cpu_register_io_memory(g_apfnMMIORead, g_apfnMMIOWrite, pVM);
+ pVM->rem.s.iMMIOMemType = cpu_register_io_memory(g_apfnMMIORead, g_apfnMMIOWrite, &pVM->rem.s.Env);
AssertReleaseMsg(pVM->rem.s.iMMIOMemType >= 0, ("pVM->rem.s.iMMIOMemType=%d\n", pVM->rem.s.iMMIOMemType));
pVM->rem.s.iHandlerMemType = cpu_register_io_memory(g_apfnHandlerRead, g_apfnHandlerWrite, pVM);
AssertReleaseMsg(pVM->rem.s.iHandlerMemType >= 0, ("pVM->rem.s.iHandlerMemType=%d\n", pVM->rem.s.iHandlerMemType));
@@ -548,67 +557,11 @@ static int remR3InitPhysRamSizeAndDirtyMap(PVM pVM, bool fGuarded)
*/
REMR3DECL(int) REMR3Term(PVM pVM)
{
-#ifdef VBOX_WITH_STATISTICS
/*
* Statistics.
*/
- STAM_DEREG(pVM, &gStatExecuteSingleInstr);
- STAM_DEREG(pVM, &gStatCompilationQEmu);
- STAM_DEREG(pVM, &gStatRunCodeQEmu);
- STAM_DEREG(pVM, &gStatTotalTimeQEmu);
- STAM_DEREG(pVM, &gStatTimers);
- STAM_DEREG(pVM, &gStatTBLookup);
- STAM_DEREG(pVM, &gStatIRQ);
- STAM_DEREG(pVM, &gStatRawCheck);
- STAM_DEREG(pVM, &gStatMemRead);
- STAM_DEREG(pVM, &gStatMemWrite);
- STAM_DEREG(pVM, &gStatGCPhys2HCVirt);
-
- STAM_DEREG(pVM, &gStatCpuGetTSC);
-
- STAM_DEREG(pVM, &gStatRefuseTFInhibit);
- STAM_DEREG(pVM, &gStatRefuseVM86);
- STAM_DEREG(pVM, &gStatRefusePaging);
- STAM_DEREG(pVM, &gStatRefusePAE);
- STAM_DEREG(pVM, &gStatRefuseIOPLNot0);
- STAM_DEREG(pVM, &gStatRefuseIF0);
- STAM_DEREG(pVM, &gStatRefuseCode16);
- STAM_DEREG(pVM, &gStatRefuseWP0);
- STAM_DEREG(pVM, &gStatRefuseRing1or2);
- STAM_DEREG(pVM, &gStatRefuseCanExecute);
- STAM_DEREG(pVM, &gaStatRefuseStale[0]);
- STAM_DEREG(pVM, &gaStatRefuseStale[1]);
- STAM_DEREG(pVM, &gaStatRefuseStale[2]);
- STAM_DEREG(pVM, &gaStatRefuseStale[3]);
- STAM_DEREG(pVM, &gaStatRefuseStale[4]);
- STAM_DEREG(pVM, &gaStatRefuseStale[5]);
- STAM_DEREG(pVM, &gStatFlushTBs);
-
- STAM_DEREG(pVM, &gStatREMGDTChange);
- STAM_DEREG(pVM, &gStatREMLDTRChange);
- STAM_DEREG(pVM, &gStatREMIDTChange);
- STAM_DEREG(pVM, &gStatREMTRChange);
-
- STAM_DEREG(pVM, &gStatSelOutOfSync[0]);
- STAM_DEREG(pVM, &gStatSelOutOfSync[1]);
- STAM_DEREG(pVM, &gStatSelOutOfSync[2]);
- STAM_DEREG(pVM, &gStatSelOutOfSync[3]);
- STAM_DEREG(pVM, &gStatSelOutOfSync[4]);
- STAM_DEREG(pVM, &gStatSelOutOfSync[5]);
-
- STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[0]);
- STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[1]);
- STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[2]);
- STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[3]);
- STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[4]);
- STAM_DEREG(pVM, &gStatSelOutOfSyncStateBack[5]);
-
- STAM_DEREG(pVM, &pVM->rem.s.Env.StatTbFlush);
-#endif /* VBOX_WITH_STATISTICS */
-
- STAM_REL_DEREG(pVM, &tb_flush_count);
- STAM_REL_DEREG(pVM, &tb_phys_invalidate_count);
- STAM_REL_DEREG(pVM, &tlb_flush_count);
+ STAMR3Deregister(pVM->pUVM, "/PROF/REM/*");
+ STAMR3Deregister(pVM->pUVM, "/REM/*");
return VINF_SUCCESS;
}
@@ -864,7 +817,7 @@ REMR3DECL(int) REMR3Step(PVM pVM, PVMCPU pVCpu)
pVM->rem.s.rc = VERR_INTERNAL_ERROR;
break;
case EXCP_EXECUTE_RAW:
- case EXCP_EXECUTE_HWACC:
+ case EXCP_EXECUTE_HM:
/** @todo: is it correct? No! */
rc = VINF_SUCCESS;
break;
@@ -953,10 +906,10 @@ REMR3DECL(int) REMR3EmulateInstruction(PVM pVM, PVMCPU pVCpu)
Log2(("REMR3EmulateInstruction: (cs:eip=%04x:%08x)\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestEIP(pVCpu)));
/* Make sure this flag is set; we might never execute remR3CanExecuteRaw in the AMD-V case.
- * CPU_RAW_HWACC makes sure we never execute interrupt handlers in the recompiler.
+ * CPU_RAW_HM makes sure we never execute interrupt handlers in the recompiler.
*/
- if (HWACCMIsEnabled(pVM))
- pVM->rem.s.Env.state |= CPU_RAW_HWACC;
+ if (HMIsEnabled(pVM))
+ pVM->rem.s.Env.state |= CPU_RAW_HM;
/* Skip the TB flush as that's rather expensive and not necessary for single instruction emulation. */
fFlushTBs = pVM->rem.s.fFlushTBs;
@@ -1052,9 +1005,9 @@ REMR3DECL(int) REMR3EmulateInstruction(PVM pVM, PVMCPU pVCpu)
/*
* Switch to hardware accelerated RAW-mode.
*/
- case EXCP_EXECUTE_HWACC:
- Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_EXECUTE_HWACC\n"));
- rc = VINF_EM_RESCHEDULE_HWACC;
+ case EXCP_EXECUTE_HM:
+ Log2(("REMR3EmulateInstruction: cpu_exec -> EXCP_EXECUTE_HM\n"));
+ rc = VINF_EM_RESCHEDULE_HM;
break;
/*
@@ -1120,14 +1073,12 @@ static int remR3RunLoggingStep(PVM pVM, PVMCPU pVCpu)
* Log the current registers state and instruction.
*/
remR3StateUpdate(pVM, pVCpu);
- DBGFR3Info(pVM, "cpumguest", NULL, NULL);
+ DBGFR3Info(pVM->pUVM, "cpumguest", NULL, NULL);
szBuf[0] = '\0';
- rc = DBGFR3DisasInstrEx(pVM,
+ rc = DBGFR3DisasInstrEx(pVM->pUVM,
pVCpu->idCpu,
- 0, /* Sel */
- 0, /* GCPtr */
- DBGF_DISAS_FLAGS_CURRENT_GUEST
- | DBGF_DISAS_FLAGS_DEFAULT_MODE,
+ 0, /* Sel */ 0, /* GCPtr */
+ DBGF_DISAS_FLAGS_CURRENT_GUEST | DBGF_DISAS_FLAGS_DEFAULT_MODE,
szBuf,
sizeof(szBuf),
NULL);
@@ -1149,7 +1100,7 @@ static int remR3RunLoggingStep(PVM pVM, PVMCPU pVCpu)
#else
pVM->rem.s.Env.interrupt_request = CPU_INTERRUPT_SINGLE_INSTR;
#endif
- if ( VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
+ if ( VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
|| pVM->rem.s.u32PendingInterrupt != REM_NO_PENDING_IRQ)
pVM->rem.s.Env.interrupt_request |= CPU_INTERRUPT_HARD;
RTLogPrintf("remR3RunLoggingStep: interrupt_request=%#x halted=%d exception_index=%#x\n", rc,
@@ -1175,8 +1126,8 @@ static int remR3RunLoggingStep(PVM pVM, PVMCPU pVCpu)
* The normal exit.
*/
case EXCP_SINGLE_INSTR:
- if ( !VM_FF_ISPENDING(pVM, VM_FF_ALL_REM_MASK)
- && !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
+ if ( !VM_FF_IS_PENDING(pVM, VM_FF_ALL_REM_MASK)
+ && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
continue;
RTLogPrintf("remR3RunLoggingStep: rc=VINF_SUCCESS w/ FFs (%#x/%#x)\n",
pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions);
@@ -1208,8 +1159,8 @@ static int remR3RunLoggingStep(PVM pVM, PVMCPU pVCpu)
#ifdef REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING
if (rc == VINF_EM_DBG_STEPPED)
{
- if ( !VM_FF_ISPENDING(pVM, VM_FF_ALL_REM_MASK)
- && !VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
+ if ( !VM_FF_IS_PENDING(pVM, VM_FF_ALL_REM_MASK)
+ && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
continue;
RTLogPrintf("remR3RunLoggingStep: rc=VINF_SUCCESS w/ FFs (%#x/%#x)\n",
@@ -1255,9 +1206,9 @@ static int remR3RunLoggingStep(PVM pVM, PVMCPU pVCpu)
/*
* Switch to hardware accelerated RAW-mode.
*/
- case EXCP_EXECUTE_HWACC:
- RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_EXECUTE_HWACC rc=VINF_EM_RESCHEDULE_HWACC\n");
- rc = VINF_EM_RESCHEDULE_HWACC;
+ case EXCP_EXECUTE_HM:
+ RTLogPrintf("remR3RunLoggingStep: cpu_exec -> EXCP_EXECUTE_HM rc=VINF_EM_RESCHEDULE_HM\n");
+ rc = VINF_EM_RESCHEDULE_HM;
break;
/*
@@ -1369,16 +1320,16 @@ REMR3DECL(int) REMR3Run(PVM pVM, PVMCPU pVCpu)
* Switch to RAW-mode.
*/
case EXCP_EXECUTE_RAW:
- Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_RAW\n"));
+ Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_RAW pc=%RGv\n", pVM->rem.s.Env.eip));
rc = VINF_EM_RESCHEDULE_RAW;
break;
/*
* Switch to hardware accelerated RAW-mode.
*/
- case EXCP_EXECUTE_HWACC:
- Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_HWACC\n"));
- rc = VINF_EM_RESCHEDULE_HWACC;
+ case EXCP_EXECUTE_HM:
+ Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_HM\n"));
+ rc = VINF_EM_RESCHEDULE_HM;
break;
/*
@@ -1435,11 +1386,11 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
if (env->state & CPU_EMULATE_SINGLE_STEP)
return false;
- if (HWACCMIsEnabled(env->pVM))
+ if (HMIsEnabled(env->pVM))
{
CPUMCTX Ctx;
- env->state |= CPU_RAW_HWACC;
+ env->state |= CPU_RAW_HM;
/*
* The simple check first...
@@ -1448,7 +1399,7 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
return false;
/*
- * Create partial context for HWACCMR3CanExecuteGuest
+ * Create partial context for HMR3CanExecuteGuest
*/
Ctx.cr0 = env->cr[0];
Ctx.cr3 = env->cr[3];
@@ -1459,14 +1410,14 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
Ctx.tr.fFlags = CPUMSELREG_FLAGS_VALID;
Ctx.tr.u64Base = env->tr.base;
Ctx.tr.u32Limit = env->tr.limit;
- Ctx.tr.Attr.u = (env->tr.flags >> 8) & 0xF0FF;
+ Ctx.tr.Attr.u = (env->tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
Ctx.ldtr.Sel = env->ldt.selector;
Ctx.ldtr.ValidSel = env->ldt.selector;
Ctx.ldtr.fFlags = CPUMSELREG_FLAGS_VALID;
Ctx.ldtr.u64Base = env->ldt.base;
Ctx.ldtr.u32Limit = env->ldt.limit;
- Ctx.ldtr.Attr.u = (env->ldt.flags >> 8) & 0xF0FF;
+ Ctx.ldtr.Attr.u = (env->ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
Ctx.idtr.cbIdt = env->idt.limit;
Ctx.idtr.pIdt = env->idt.base;
@@ -1484,42 +1435,42 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
Ctx.cs.fFlags = CPUMSELREG_FLAGS_VALID;
Ctx.cs.u64Base = env->segs[R_CS].base;
Ctx.cs.u32Limit = env->segs[R_CS].limit;
- Ctx.cs.Attr.u = (env->segs[R_CS].flags >> 8) & 0xF0FF;
+ Ctx.cs.Attr.u = (env->segs[R_CS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
Ctx.ds.Sel = env->segs[R_DS].selector;
Ctx.ds.ValidSel = env->segs[R_DS].selector;
Ctx.ds.fFlags = CPUMSELREG_FLAGS_VALID;
Ctx.ds.u64Base = env->segs[R_DS].base;
Ctx.ds.u32Limit = env->segs[R_DS].limit;
- Ctx.ds.Attr.u = (env->segs[R_DS].flags >> 8) & 0xF0FF;
+ Ctx.ds.Attr.u = (env->segs[R_DS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
Ctx.es.Sel = env->segs[R_ES].selector;
Ctx.es.ValidSel = env->segs[R_ES].selector;
Ctx.es.fFlags = CPUMSELREG_FLAGS_VALID;
Ctx.es.u64Base = env->segs[R_ES].base;
Ctx.es.u32Limit = env->segs[R_ES].limit;
- Ctx.es.Attr.u = (env->segs[R_ES].flags >> 8) & 0xF0FF;
+ Ctx.es.Attr.u = (env->segs[R_ES].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
Ctx.fs.Sel = env->segs[R_FS].selector;
Ctx.fs.ValidSel = env->segs[R_FS].selector;
Ctx.fs.fFlags = CPUMSELREG_FLAGS_VALID;
Ctx.fs.u64Base = env->segs[R_FS].base;
Ctx.fs.u32Limit = env->segs[R_FS].limit;
- Ctx.fs.Attr.u = (env->segs[R_FS].flags >> 8) & 0xF0FF;
+ Ctx.fs.Attr.u = (env->segs[R_FS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
Ctx.gs.Sel = env->segs[R_GS].selector;
Ctx.gs.ValidSel = env->segs[R_GS].selector;
Ctx.gs.fFlags = CPUMSELREG_FLAGS_VALID;
Ctx.gs.u64Base = env->segs[R_GS].base;
Ctx.gs.u32Limit = env->segs[R_GS].limit;
- Ctx.gs.Attr.u = (env->segs[R_GS].flags >> 8) & 0xF0FF;
+ Ctx.gs.Attr.u = (env->segs[R_GS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
Ctx.ss.Sel = env->segs[R_SS].selector;
Ctx.ss.ValidSel = env->segs[R_SS].selector;
Ctx.ss.fFlags = CPUMSELREG_FLAGS_VALID;
Ctx.ss.u64Base = env->segs[R_SS].base;
Ctx.ss.u32Limit = env->segs[R_SS].limit;
- Ctx.ss.Attr.u = (env->segs[R_SS].flags >> 8) & 0xF0FF;
+ Ctx.ss.Attr.u = (env->segs[R_SS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
Ctx.msrEFER = env->efer;
@@ -1527,9 +1478,9 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
*
* Typically only 32-bits protected mode, with paging enabled, code is allowed here.
*/
- if (HWACCMR3CanExecuteGuest(env->pVM, &Ctx) == true)
+ if (HMR3CanExecuteGuest(env->pVM, &Ctx) == true)
{
- *piException = EXCP_EXECUTE_HWACC;
+ *piException = EXCP_EXECUTE_HM;
return true;
}
return false;
@@ -1631,8 +1582,17 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
return false;
}
- // Only R0
- if (((fFlags >> HF_CPL_SHIFT) & 3) != 0)
+ if (EMIsRawRing1Enabled(env->pVM))
+ {
+ /* Only ring 0 and 1 supervisor code. */
+ if (((fFlags >> HF_CPL_SHIFT) & 3) == 2) /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */
+ {
+ Log2(("raw r0 mode refused: CPL %d\n", (fFlags >> HF_CPL_SHIFT) & 3));
+ return false;
+ }
+ }
+ /* Only R0. */
+ else if (((fFlags >> HF_CPL_SHIFT) & 3) != 0)
{
STAM_COUNTER_INC(&gStatRefuseRing1or2);
Log2(("raw r0 mode refused: CPL %d\n", ((fFlags >> HF_CPL_SHIFT) & 3) ));
@@ -1646,12 +1606,14 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
return false;
}
+#ifdef VBOX_WITH_RAW_MODE
if (PATMIsPatchGCAddr(env->pVM, eip))
{
Log2(("raw r0 mode forced: patch code\n"));
*piException = EXCP_EXECUTE_RAW;
return true;
}
+#endif
#if !defined(VBOX_ALLOW_IF0) && !defined(VBOX_RUN_INTERRUPT_GATE_HANDLERS)
if (!(env->eflags & IF_MASK))
@@ -1663,6 +1625,13 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
}
#endif
+#ifndef VBOX_WITH_RAW_RING1
+ if (((env->eflags >> IOPL_SHIFT) & 3) != 0)
+ {
+ Log2(("raw r0 mode refused: IOPL %d\n", ((env->eflags >> IOPL_SHIFT) & 3)));
+ return false;
+ }
+#endif
env->state |= CPU_RAW_RING0;
}
@@ -1684,37 +1653,37 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
{
Log2(("raw mode refused: stale CS (%#x)\n", env->segs[R_CS].selector));
STAM_COUNTER_INC(&gaStatRefuseStale[R_CS]);
- return EMSTATE_REM;
+ return false;
}
if (env->segs[R_SS].fVBoxFlags & CPUMSELREG_FLAGS_STALE)
{
Log2(("raw mode refused: stale SS (%#x)\n", env->segs[R_SS].selector));
STAM_COUNTER_INC(&gaStatRefuseStale[R_SS]);
- return EMSTATE_REM;
+ return false;
}
if (env->segs[R_DS].fVBoxFlags & CPUMSELREG_FLAGS_STALE)
{
Log2(("raw mode refused: stale DS (%#x)\n", env->segs[R_DS].selector));
STAM_COUNTER_INC(&gaStatRefuseStale[R_DS]);
- return EMSTATE_REM;
+ return false;
}
if (env->segs[R_ES].fVBoxFlags & CPUMSELREG_FLAGS_STALE)
{
Log2(("raw mode refused: stale ES (%#x)\n", env->segs[R_ES].selector));
STAM_COUNTER_INC(&gaStatRefuseStale[R_ES]);
- return EMSTATE_REM;
+ return false;
}
if (env->segs[R_FS].fVBoxFlags & CPUMSELREG_FLAGS_STALE)
{
Log2(("raw mode refused: stale FS (%#x)\n", env->segs[R_FS].selector));
STAM_COUNTER_INC(&gaStatRefuseStale[R_FS]);
- return EMSTATE_REM;
+ return false;
}
if (env->segs[R_GS].fVBoxFlags & CPUMSELREG_FLAGS_STALE)
{
Log2(("raw mode refused: stale GS (%#x)\n", env->segs[R_GS].selector));
STAM_COUNTER_INC(&gaStatRefuseStale[R_GS]);
- return EMSTATE_REM;
+ return false;
}
/* Assert(env->pVCpu && PGMPhysIsA20Enabled(env->pVCpu));*/
@@ -1723,6 +1692,7 @@ bool remR3CanExecuteRaw(CPUX86State *env, RTGCPTR eip, unsigned fFlags, int *piE
}
+#ifdef VBOX_WITH_RAW_MODE
/**
* Fetches a code byte.
*
@@ -1738,6 +1708,7 @@ bool remR3GetOpcode(CPUX86State *env, RTGCPTR GCPtrInstr, uint8_t *pu8Byte)
return true;
return false;
}
+#endif /* VBOX_WITH_RAW_MODE */
/**
@@ -1762,7 +1733,7 @@ void remR3FlushPage(CPUX86State *env, RTGCPTR GCPtr)
*/
if (pVM->rem.s.fIgnoreInvlPg || pVM->rem.s.cIgnoreAll)
return;
- Log(("remR3FlushPage: GCPtr=%RGv\n", GCPtr));
+ LogFlow(("remR3FlushPage: GCPtr=%RGv\n", GCPtr));
Assert(pVM->rem.s.fInREM || pVM->rem.s.fInStateSync);
//RAWEx_ProfileStop(env, STATS_QEMU_TOTAL);
@@ -1774,8 +1745,10 @@ void remR3FlushPage(CPUX86State *env, RTGCPTR GCPtr)
Assert(pCtx);
pCtx->cr0 = env->cr[0];
pCtx->cr3 = env->cr[3];
- if ((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME)
+#ifdef VBOX_WITH_RAW_MODE
+ if (((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME) && !HMIsEnabled(pVM))
VMCPU_FF_SET(env->pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#endif
pCtx->cr4 = env->cr[4];
/*
@@ -1834,7 +1807,7 @@ void remR3ProtectCode(CPUX86State *env, RTGCPTR GCPtr)
&& !(env->state & CPU_EMULATE_SINGLE_INSTR) /* ignore during single instruction execution */
&& (((env->hflags >> HF_CPL_SHIFT) & 3) == 0) /* supervisor mode only */
&& !(env->eflags & VM_MASK) /* no V86 mode */
- && !HWACCMIsEnabled(env->pVM))
+ && !HMIsEnabled(env->pVM))
CSAMR3MonitorPage(env->pVM, GCPtr, CSAM_TAG_REM);
#endif
}
@@ -1854,7 +1827,7 @@ void remR3UnprotectCode(CPUX86State *env, RTGCPTR GCPtr)
&& !(env->state & CPU_EMULATE_SINGLE_INSTR) /* ignore during single instruction execution */
&& (((env->hflags >> HF_CPL_SHIFT) & 3) == 0) /* supervisor mode only */
&& !(env->eflags & VM_MASK) /* no V86 mode */
- && !HWACCMIsEnabled(env->pVM))
+ && !HMIsEnabled(env->pVM))
CSAMR3UnmonitorPage(env->pVM, GCPtr, CSAM_TAG_REM);
#endif
}
@@ -1895,8 +1868,10 @@ void remR3FlushTLB(CPUX86State *env, bool fGlobal)
Assert(pCtx);
pCtx->cr0 = env->cr[0];
pCtx->cr3 = env->cr[3];
- if ((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME)
+#ifdef VBOX_WITH_RAW_MODE
+ if (((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME) && !HMIsEnabled(pVM))
VMCPU_FF_SET(env->pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#endif
pCtx->cr4 = env->cr[4];
/*
@@ -1927,16 +1902,25 @@ void remR3ChangeCpuMode(CPUX86State *env)
return;
Assert(pVM->rem.s.fInREM);
+ pCtx = (PCPUMCTX)pVM->rem.s.pCtx;
+ Assert(pCtx);
+
+ /*
+ * Notify PGM about WP0 being enabled (like CPUSetGuestCR0 does).
+ */
+ if (((env->cr[0] ^ pCtx->cr0) & X86_CR0_WP) && (env->cr[0] & X86_CR0_WP))
+ PGMCr0WpEnabled(env->pVCpu);
+
/*
* Update the control registers before calling PGMChangeMode()
* as it may need to map whatever cr3 is pointing to.
*/
- pCtx = (PCPUMCTX)pVM->rem.s.pCtx;
- Assert(pCtx);
pCtx->cr0 = env->cr[0];
pCtx->cr3 = env->cr[3];
- if ((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME)
+#ifdef VBOX_WITH_RAW_MODE
+ if (((env->cr[4] ^ pCtx->cr4) & X86_CR4_VME) && !HMIsEnabled(pVM))
VMCPU_FF_SET(env->pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#endif
pCtx->cr4 = env->cr[4];
#ifdef TARGET_X86_64
efer = env->efer;
@@ -2034,7 +2018,10 @@ int remR3NotifyTrap(CPUX86State *env, uint32_t uTrap, uint32_t uErrorCode, RTGCP
return VERR_REM_TOO_MANY_TRAPS;
}
if(pVM->rem.s.uPendingException != uTrap || pVM->rem.s.uPendingExcptEIP != env->eip || pVM->rem.s.uPendingExcptCR2 != env->cr[2])
+ {
+ Log(("remR3NotifyTrap: uTrap=%#x set as pending\n", uTrap));
pVM->rem.s.cPendingExceptions = 1;
+ }
pVM->rem.s.uPendingException = uTrap;
pVM->rem.s.uPendingExcptEIP = env->eip;
pVM->rem.s.uPendingExcptCR2 = env->cr[2];
@@ -2071,7 +2058,9 @@ void remR3TrapClear(PVM pVM)
*/
void remR3RecordCall(CPUX86State *env)
{
+#ifdef VBOX_WITH_RAW_MODE
CSAMR3RecordCallAddress(env->pVM, env->eip);
+#endif
}
@@ -2235,7 +2224,7 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
/* Update the inhibit IRQ mask. */
pVM->rem.s.Env.hflags &= ~HF_INHIBIT_IRQ_MASK;
- if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
+ if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
{
RTGCPTR InhibitPC = EMGetInhibitInterruptsPC(pVCpu);
if (InhibitPC == pCtx->rip)
@@ -2335,7 +2324,7 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
pVM->rem.s.Env.ldt.fVBoxFlags = pCtx->ldtr.fFlags;
pVM->rem.s.Env.ldt.base = pCtx->ldtr.u64Base;
pVM->rem.s.Env.ldt.limit = pCtx->ldtr.u32Limit;
- pVM->rem.s.Env.ldt.flags = (pCtx->ldtr.Attr.u << 8) & 0xFFFFFF;
+ pVM->rem.s.Env.ldt.flags = (pCtx->ldtr.Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT;
}
else
{
@@ -2368,8 +2357,8 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
pVM->rem.s.Env.tr.fVBoxFlags = pCtx->tr.fFlags;
pVM->rem.s.Env.tr.base = pCtx->tr.u64Base;
pVM->rem.s.Env.tr.limit = pCtx->tr.u32Limit;
- pVM->rem.s.Env.tr.flags = (pCtx->tr.Attr.u << 8) & 0xFFFFFF;
- /* Note! do_interrupt will fault if the busy flag is still set... */
+ pVM->rem.s.Env.tr.flags = (pCtx->tr.Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT;
+ /* Note! do_interrupt will fault if the busy flag is still set... */ /** @todo so fix do_interrupt then! */
pVM->rem.s.Env.tr.flags &= ~DESC_TSS_BUSY_MASK;
/*
@@ -2393,7 +2382,7 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
(a_pVBoxSReg)->Sel, \
(a_pVBoxSReg)->u64Base, \
(a_pVBoxSReg)->u32Limit, \
- ((a_pVBoxSReg)->Attr.u << 8) & 0xFFFFFF); \
+ ((a_pVBoxSReg)->Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT); \
(a_pRemSReg)->fVBoxFlags = (a_pVBoxSReg)->fFlags; \
} \
/* This only-reload-if-changed stuff is the old approach, we should ditch it. */ \
@@ -2437,6 +2426,9 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
if (enmType != TRPM_SOFTWARE_INT)
{
pVM->rem.s.Env.exception_is_int = 0;
+#ifdef IEM_VERIFICATION_MODE /* Ugly hack, needs proper fixing. */
+ pVM->rem.s.Env.exception_is_int = enmType == TRPM_HARDWARE_INT ? 0x42 : 0;
+#endif
pVM->rem.s.Env.exception_next_eip = pVM->rem.s.Env.eip;
}
else
@@ -2467,14 +2459,14 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
{
switch (u8TrapNo)
{
- case 0x0e:
+ case X86_XCPT_PF:
pVM->rem.s.Env.cr[2] = TRPMGetFaultAddress(pVCpu);
/* fallthru */
- case 0x0a: case 0x0b: case 0x0c: case 0x0d:
+ case X86_XCPT_TS: case X86_XCPT_NP: case X86_XCPT_SS: case X86_XCPT_GP:
pVM->rem.s.Env.error_code = TRPMGetErrorCode(pVCpu);
break;
- case 0x11: case 0x08:
+ case X86_XCPT_AC: case X86_XCPT_DF:
default:
pVM->rem.s.Env.error_code = 0;
break;
@@ -2498,7 +2490,7 @@ REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu)
*/
pVM->rem.s.Env.interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB | CPU_INTERRUPT_TIMER);
if ( pVM->rem.s.u32PendingInterrupt != REM_NO_PENDING_IRQ
- || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
+ || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
pVM->rem.s.Env.interrupt_request |= CPU_INTERRUPT_HARD;
/*
@@ -2592,8 +2584,8 @@ REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu)
pCtx->a_sreg.fFlags = CPUMSELREG_FLAGS_VALID; \
pCtx->a_sreg.u64Base = pVM->rem.s.Env.segs[R_##a_SREG].base; \
pCtx->a_sreg.u32Limit = pVM->rem.s.Env.segs[R_##a_SREG].limit; \
- /* Note! QEmu saves the 2nd dword of the descriptor; we should store the attribute word only! */ \
- pCtx->a_sreg.Attr.u = (pVM->rem.s.Env.segs[R_##a_SREG].flags >> 8) & 0xF0FF; \
+ /* Note! QEmu saves the 2nd dword of the descriptor; we (VT-x/AMD-V) keep only the attributes! */ \
+ pCtx->a_sreg.Attr.u = (pVM->rem.s.Env.segs[R_##a_SREG].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; \
} \
else \
{ \
@@ -2620,8 +2612,10 @@ REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu)
pCtx->cr0 = pVM->rem.s.Env.cr[0];
pCtx->cr2 = pVM->rem.s.Env.cr[2];
pCtx->cr3 = pVM->rem.s.Env.cr[3];
- if ((pVM->rem.s.Env.cr[4] ^ pCtx->cr4) & X86_CR4_VME)
+#ifdef VBOX_WITH_RAW_MODE
+ if (((pVM->rem.s.Env.cr[4] ^ pCtx->cr4) & X86_CR4_VME) && !HMIsEnabled(pVM))
VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#endif
pCtx->cr4 = pVM->rem.s.Env.cr[4];
for (i = 0; i < 8; i++)
@@ -2632,7 +2626,10 @@ REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu)
{
pCtx->gdtr.pGdt = pVM->rem.s.Env.gdt.base;
STAM_COUNTER_INC(&gStatREMGDTChange);
- VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+#ifdef VBOX_WITH_RAW_MODE
+ if (!HMIsEnabled(pVM))
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+#endif
}
pCtx->idtr.cbIdt = pVM->rem.s.Env.idt.limit;
@@ -2640,14 +2637,17 @@ REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu)
{
pCtx->idtr.pIdt = pVM->rem.s.Env.idt.base;
STAM_COUNTER_INC(&gStatREMIDTChange);
- VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
+#ifdef VBOX_WITH_RAW_MODE
+ if (!HMIsEnabled(pVM))
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
+#endif
}
if ( pCtx->ldtr.Sel != pVM->rem.s.Env.ldt.selector
|| pCtx->ldtr.ValidSel != pVM->rem.s.Env.ldt.selector
|| pCtx->ldtr.u64Base != pVM->rem.s.Env.ldt.base
|| pCtx->ldtr.u32Limit != pVM->rem.s.Env.ldt.limit
- || pCtx->ldtr.Attr.u != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF)
+ || pCtx->ldtr.Attr.u != ((pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK)
|| !(pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID)
)
{
@@ -2656,18 +2656,21 @@ REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu)
pCtx->ldtr.fFlags = CPUMSELREG_FLAGS_VALID;
pCtx->ldtr.u64Base = pVM->rem.s.Env.ldt.base;
pCtx->ldtr.u32Limit = pVM->rem.s.Env.ldt.limit;
- pCtx->ldtr.Attr.u = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;
+ pCtx->ldtr.Attr.u = (pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
STAM_COUNTER_INC(&gStatREMLDTRChange);
- VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
+#ifdef VBOX_WITH_RAW_MODE
+ if (!HMIsEnabled(pVM))
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
+#endif
}
if ( pCtx->tr.Sel != pVM->rem.s.Env.tr.selector
|| pCtx->tr.ValidSel != pVM->rem.s.Env.tr.selector
|| pCtx->tr.u64Base != pVM->rem.s.Env.tr.base
|| pCtx->tr.u32Limit != pVM->rem.s.Env.tr.limit
- /* Qemu and AMD/Intel have different ideas about the busy flag ... */
- || pCtx->tr.Attr.u != ( (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF
- ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8
+ /* Qemu and AMD/Intel have different ideas about the busy flag ... */ /** @todo just fix qemu! */
+ || pCtx->tr.Attr.u != ( (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE)
+ ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT
: 0)
|| !(pCtx->tr.fFlags & CPUMSELREG_FLAGS_VALID)
)
@@ -2675,17 +2678,21 @@ REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu)
Log(("REM: TR changed! %#x{%#llx,%#x,%#x} -> %#x{%llx,%#x,%#x}\n",
pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
pVM->rem.s.Env.tr.selector, (uint64_t)pVM->rem.s.Env.tr.base, pVM->rem.s.Env.tr.limit,
- (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8 : 0));
+ (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE)
+ ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT : 0));
pCtx->tr.Sel = pVM->rem.s.Env.tr.selector;
pCtx->tr.ValidSel = pVM->rem.s.Env.tr.selector;
pCtx->tr.fFlags = CPUMSELREG_FLAGS_VALID;
pCtx->tr.u64Base = pVM->rem.s.Env.tr.base;
pCtx->tr.u32Limit = pVM->rem.s.Env.tr.limit;
- pCtx->tr.Attr.u = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;
- if (pCtx->tr.Attr.u)
- pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
+ pCtx->tr.Attr.u = (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
+ if (pCtx->tr.Attr.u & ~DESC_INTEL_UNUSABLE)
+ pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> SEL_FLAGS_SHIFT;
STAM_COUNTER_INC(&gStatREMTRChange);
- VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#ifdef VBOX_WITH_RAW_MODE
+ if (!HMIsEnabled(pVM))
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#endif
}
/* Sysenter MSR */
@@ -2711,7 +2718,7 @@ REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu)
EMSetInhibitInterruptsPC(pVCpu, pCtx->rip);
VMCPU_FF_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
}
- else if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
+ else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
{
Log(("Clearing VMCPU_FF_INHIBIT_INTERRUPTS at %RGv - successor %RGv (REM#2)\n", (RTGCPTR)pCtx->rip, EMGetInhibitInterruptsPC(pVCpu)));
VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
@@ -2725,29 +2732,33 @@ REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu)
if ( pVM->rem.s.Env.exception_index >= 0
&& pVM->rem.s.Env.exception_index < 256)
{
+ /* This cannot be a hardware-interrupt because exception_index < EXCP_INTERRUPT. */
int rc;
Log(("REMR3StateBack: Pending trap %x %d\n", pVM->rem.s.Env.exception_index, pVM->rem.s.Env.exception_is_int));
- rc = TRPMAssertTrap(pVCpu, pVM->rem.s.Env.exception_index, (pVM->rem.s.Env.exception_is_int) ? TRPM_SOFTWARE_INT : TRPM_HARDWARE_INT);
+ TRPMEVENT enmType = pVM->rem.s.Env.exception_is_int ? TRPM_SOFTWARE_INT : TRPM_TRAP;
+ rc = TRPMAssertTrap(pVCpu, pVM->rem.s.Env.exception_index, enmType);
AssertRC(rc);
- switch (pVM->rem.s.Env.exception_index)
+ if (enmType == TRPM_TRAP)
{
- case 0x0e:
- TRPMSetFaultAddress(pVCpu, pCtx->cr2);
- /* fallthru */
- case 0x0a: case 0x0b: case 0x0c: case 0x0d:
- case 0x11: case 0x08: /* 0 */
- TRPMSetErrorCode(pVCpu, pVM->rem.s.Env.error_code);
- break;
+ switch (pVM->rem.s.Env.exception_index)
+ {
+ case X86_XCPT_PF:
+ TRPMSetFaultAddress(pVCpu, pCtx->cr2);
+ /* fallthru */
+ case X86_XCPT_TS: case X86_XCPT_NP: case X86_XCPT_SS: case X86_XCPT_GP:
+ case X86_XCPT_AC: case X86_XCPT_DF: /* 0 */
+ TRPMSetErrorCode(pVCpu, pVM->rem.s.Env.error_code);
+ break;
+ }
}
-
}
/*
* We're not longer in REM mode.
*/
CPUMR3RemLeave(pVCpu,
- HWACCMIsEnabled(pVM)
+ HMIsEnabled(pVM)
|| ( pVM->rem.s.Env.segs[R_SS].newselector
| pVM->rem.s.Env.segs[R_GS].newselector
| pVM->rem.s.Env.segs[R_FS].newselector
@@ -2842,8 +2853,10 @@ static void remR3StateUpdate(PVM pVM, PVMCPU pVCpu)
pCtx->cr0 = pVM->rem.s.Env.cr[0];
pCtx->cr2 = pVM->rem.s.Env.cr[2];
pCtx->cr3 = pVM->rem.s.Env.cr[3];
- if ((pVM->rem.s.Env.cr[4] ^ pCtx->cr4) & X86_CR4_VME)
+#ifdef VBOX_WITH_RAW_MODE
+ if (((pVM->rem.s.Env.cr[4] ^ pCtx->cr4) & X86_CR4_VME) && !HMIsEnabled(pVM))
VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#endif
pCtx->cr4 = pVM->rem.s.Env.cr[4];
for (i = 0; i < 8; i++)
@@ -2854,7 +2867,10 @@ static void remR3StateUpdate(PVM pVM, PVMCPU pVCpu)
{
pCtx->gdtr.pGdt = (RTGCPTR)pVM->rem.s.Env.gdt.base;
STAM_COUNTER_INC(&gStatREMGDTChange);
- VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+#ifdef VBOX_WITH_RAW_MODE
+ if (!HMIsEnabled(pVM))
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
+#endif
}
pCtx->idtr.cbIdt = pVM->rem.s.Env.idt.limit;
@@ -2862,14 +2878,17 @@ static void remR3StateUpdate(PVM pVM, PVMCPU pVCpu)
{
pCtx->idtr.pIdt = (RTGCPTR)pVM->rem.s.Env.idt.base;
STAM_COUNTER_INC(&gStatREMIDTChange);
- VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
+#ifdef VBOX_WITH_RAW_MODE
+ if (!HMIsEnabled(pVM))
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
+#endif
}
if ( pCtx->ldtr.Sel != pVM->rem.s.Env.ldt.selector
|| pCtx->ldtr.ValidSel != pVM->rem.s.Env.ldt.selector
|| pCtx->ldtr.u64Base != pVM->rem.s.Env.ldt.base
|| pCtx->ldtr.u32Limit != pVM->rem.s.Env.ldt.limit
- || pCtx->ldtr.Attr.u != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF)
+ || pCtx->ldtr.Attr.u != ((pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK)
|| !(pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID)
)
{
@@ -2878,9 +2897,12 @@ static void remR3StateUpdate(PVM pVM, PVMCPU pVCpu)
pCtx->ldtr.fFlags = CPUMSELREG_FLAGS_VALID;
pCtx->ldtr.u64Base = pVM->rem.s.Env.ldt.base;
pCtx->ldtr.u32Limit = pVM->rem.s.Env.ldt.limit;
- pCtx->ldtr.Attr.u = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;
+ pCtx->ldtr.Attr.u = (pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
STAM_COUNTER_INC(&gStatREMLDTRChange);
- VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
+#ifdef VBOX_WITH_RAW_MODE
+ if (!HMIsEnabled(pVM))
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
+#endif
}
if ( pCtx->tr.Sel != pVM->rem.s.Env.tr.selector
@@ -2888,8 +2910,8 @@ static void remR3StateUpdate(PVM pVM, PVMCPU pVCpu)
|| pCtx->tr.u64Base != pVM->rem.s.Env.tr.base
|| pCtx->tr.u32Limit != pVM->rem.s.Env.tr.limit
/* Qemu and AMD/Intel have different ideas about the busy flag ... */
- || pCtx->tr.Attr.u != ( (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF
- ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8
+ || pCtx->tr.Attr.u != ( (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE)
+ ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT
: 0)
|| !(pCtx->tr.fFlags & CPUMSELREG_FLAGS_VALID)
)
@@ -2897,17 +2919,21 @@ static void remR3StateUpdate(PVM pVM, PVMCPU pVCpu)
Log(("REM: TR changed! %#x{%#llx,%#x,%#x} -> %#x{%llx,%#x,%#x}\n",
pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u,
pVM->rem.s.Env.tr.selector, (uint64_t)pVM->rem.s.Env.tr.base, pVM->rem.s.Env.tr.limit,
- (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8 : 0));
+ (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE)
+ ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT : 0));
pCtx->tr.Sel = pVM->rem.s.Env.tr.selector;
pCtx->tr.ValidSel = pVM->rem.s.Env.tr.selector;
pCtx->tr.fFlags = CPUMSELREG_FLAGS_VALID;
pCtx->tr.u64Base = pVM->rem.s.Env.tr.base;
pCtx->tr.u32Limit = pVM->rem.s.Env.tr.limit;
- pCtx->tr.Attr.u = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;
- if (pCtx->tr.Attr.u)
- pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> 8;
+ pCtx->tr.Attr.u = (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK;
+ if (pCtx->tr.Attr.u & ~DESC_INTEL_UNUSABLE)
+ pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> SEL_FLAGS_SHIFT;
STAM_COUNTER_INC(&gStatREMTRChange);
- VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#ifdef VBOX_WITH_RAW_MODE
+ if (!HMIsEnabled(pVM))
+ VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
+#endif
}
/* Sysenter MSR */
@@ -2992,7 +3018,7 @@ REMR3DECL(void) REMR3ReplayHandlerNotifications(PVM pVM)
VM_ASSERT_EMT(pVM);
/** @todo this isn't ensuring correct replay order. */
- if (VM_FF_TESTANDCLEAR(pVM, VM_FF_REM_HANDLER_NOTIFY))
+ if (VM_FF_TEST_AND_CLEAR(pVM, VM_FF_REM_HANDLER_NOTIFY))
{
uint32_t idxNext;
uint32_t idxRevHead;
@@ -3489,11 +3515,11 @@ target_ulong remR3PhysGetPhysicalAddressCode(CPUX86State *env,
LogRel(("\nTrying to execute code with memory type addr_code=%RGv addend=%RGp at %RGv! (iHandlerMemType=%#x iMMIOMemType=%#x IOTLB=%RGp)\n"
"*** handlers\n",
(RTGCPTR)pTLBEntry->addr_code, (RTGCPHYS)pTLBEntry->addend, (RTGCPTR)addr, pVM->rem.s.iHandlerMemType, pVM->rem.s.iMMIOMemType, (RTGCPHYS)ioTLBEntry));
- DBGFR3Info(pVM, "handlers", NULL, DBGFR3InfoLogRelHlp());
+ DBGFR3Info(pVM->pUVM, "handlers", NULL, DBGFR3InfoLogRelHlp());
LogRel(("*** mmio\n"));
- DBGFR3Info(pVM, "mmio", NULL, DBGFR3InfoLogRelHlp());
+ DBGFR3Info(pVM->pUVM, "mmio", NULL, DBGFR3InfoLogRelHlp());
LogRel(("*** phys\n"));
- DBGFR3Info(pVM, "phys", NULL, DBGFR3InfoLogRelHlp());
+ DBGFR3Info(pVM->pUVM, "phys", NULL, DBGFR3InfoLogRelHlp());
cpu_abort(env, "Trying to execute code with memory type addr_code=%RGv addend=%RGp at %RGv. (iHandlerMemType=%#x iMMIOMemType=%#x)\n",
(RTGCPTR)pTLBEntry->addr_code, (RTGCPHYS)pTLBEntry->addend, (RTGCPTR)addr, pVM->rem.s.iHandlerMemType, pVM->rem.s.iMMIOMemType);
AssertFatalFailed();
@@ -3764,59 +3790,65 @@ void remR3PhysWriteU64(RTGCPHYS DstGCPhys, uint64_t val)
#define LOG_GROUP LOG_GROUP_REM_MMIO
/** Read MMIO memory. */
-static uint32_t remR3MMIOReadU8(void *pvVM, target_phys_addr_t GCPhys)
+static uint32_t remR3MMIOReadU8(void *pvEnv, target_phys_addr_t GCPhys)
{
- uint32_t u32 = 0;
- int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 1);
+ CPUX86State *env = (CPUX86State *)pvEnv;
+ uint32_t u32 = 0;
+ int rc = IOMMMIORead(env->pVM, env->pVCpu, GCPhys, &u32, 1);
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
Log2(("remR3MMIOReadU8: GCPhys=%RGp -> %02x\n", (RTGCPHYS)GCPhys, u32));
return u32;
}
/** Read MMIO memory. */
-static uint32_t remR3MMIOReadU16(void *pvVM, target_phys_addr_t GCPhys)
+static uint32_t remR3MMIOReadU16(void *pvEnv, target_phys_addr_t GCPhys)
{
- uint32_t u32 = 0;
- int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 2);
+ CPUX86State *env = (CPUX86State *)pvEnv;
+ uint32_t u32 = 0;
+ int rc = IOMMMIORead(env->pVM, env->pVCpu, GCPhys, &u32, 2);
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
Log2(("remR3MMIOReadU16: GCPhys=%RGp -> %04x\n", (RTGCPHYS)GCPhys, u32));
return u32;
}
/** Read MMIO memory. */
-static uint32_t remR3MMIOReadU32(void *pvVM, target_phys_addr_t GCPhys)
+static uint32_t remR3MMIOReadU32(void *pvEnv, target_phys_addr_t GCPhys)
{
- uint32_t u32 = 0;
- int rc = IOMMMIORead((PVM)pvVM, GCPhys, &u32, 4);
+ CPUX86State *env = (CPUX86State *)pvEnv;
+ uint32_t u32 = 0;
+ int rc = IOMMMIORead(env->pVM, env->pVCpu, GCPhys, &u32, 4);
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
Log2(("remR3MMIOReadU32: GCPhys=%RGp -> %08x\n", (RTGCPHYS)GCPhys, u32));
return u32;
}
/** Write to MMIO memory. */
-static void remR3MMIOWriteU8(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
+static void remR3MMIOWriteU8(void *pvEnv, target_phys_addr_t GCPhys, uint32_t u32)
{
- int rc;
+ CPUX86State *env = (CPUX86State *)pvEnv;
+ int rc;
Log2(("remR3MMIOWriteU8: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
- rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 1);
+ rc = IOMMMIOWrite(env->pVM, env->pVCpu, GCPhys, u32, 1);
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
}
/** Write to MMIO memory. */
-static void remR3MMIOWriteU16(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
+static void remR3MMIOWriteU16(void *pvEnv, target_phys_addr_t GCPhys, uint32_t u32)
{
- int rc;
+ CPUX86State *env = (CPUX86State *)pvEnv;
+ int rc;
Log2(("remR3MMIOWriteU16: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
- rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 2);
+ rc = IOMMMIOWrite(env->pVM, env->pVCpu, GCPhys, u32, 2);
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
}
/** Write to MMIO memory. */
-static void remR3MMIOWriteU32(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32)
+static void remR3MMIOWriteU32(void *pvEnv, target_phys_addr_t GCPhys, uint32_t u32)
{
- int rc;
+ CPUX86State *env = (CPUX86State *)pvEnv;
+ int rc;
Log2(("remR3MMIOWriteU32: GCPhys=%RGp u32=%#x\n", (RTGCPHYS)GCPhys, u32));
- rc = IOMMMIOWrite((PVM)pvVM, GCPhys, u32, 4);
+ rc = IOMMMIOWrite(env->pVM, env->pVCpu, GCPhys, u32, 4);
AssertMsg(rc == VINF_SUCCESS, ("rc=%Rrc\n", rc)); NOREF(rc);
}
@@ -3922,9 +3954,10 @@ REMR3DECL(int) REMR3DisasEnableStepping(PVM pVM, bool fEnable)
/**
* External Debugger Command: .remstep [on|off|1|0]
*/
-static DECLCALLBACK(int) remR3CmdDisasEnableStepping(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs)
+static DECLCALLBACK(int) remR3CmdDisasEnableStepping(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PUVM pUVM, PCDBGCVAR paArgs, unsigned cArgs)
{
int rc;
+ PVM pVM = pUVM->pVM;
if (cArgs == 0)
/*
@@ -3987,7 +4020,7 @@ bool remR3DisasInstr(CPUX86State *env, int f32BitCode, char *pszPrefix)
* Log registers if requested.
*/
if (fLog2)
- DBGFR3InfoLog(pVM, "cpumguest", pszPrefix);
+ DBGFR3_INFO_LOG(pVM, "cpumguest", pszPrefix);
/*
* Disassemble to log.
@@ -3997,12 +4030,10 @@ bool remR3DisasInstr(CPUX86State *env, int f32BitCode, char *pszPrefix)
PVMCPU pVCpu = VMMGetCpu(pVM);
char szBuf[256];
szBuf[0] = '\0';
- int rc = DBGFR3DisasInstrEx(pVCpu->pVMR3,
+ int rc = DBGFR3DisasInstrEx(pVCpu->pVMR3->pUVM,
pVCpu->idCpu,
- 0, /* Sel */
- 0, /* GCPtr */
- DBGF_DISAS_FLAGS_CURRENT_GUEST
- | DBGF_DISAS_FLAGS_DEFAULT_MODE,
+ 0, /* Sel */ 0, /* GCPtr */
+ DBGF_DISAS_FLAGS_CURRENT_GUEST | DBGF_DISAS_FLAGS_DEFAULT_MODE,
szBuf,
sizeof(szBuf),
NULL);
@@ -4091,7 +4122,7 @@ void target_disas(FILE *phFile, target_ulong uCode, target_ulong cb, int fFlags)
{
char szBuf[256];
uint32_t cbInstr;
- int rc = DBGFR3DisasInstrEx(pVM,
+ int rc = DBGFR3DisasInstrEx(pVM->pUVM,
pVCpu->idCpu,
cs,
eip,
@@ -4130,7 +4161,8 @@ const char *lookup_symbol(target_ulong orig_addr)
RTDBGSYMBOL Sym;
DBGFADDRESS Addr;
- int rc = DBGFR3AsSymbolByAddr(pVM, DBGF_AS_GLOBAL, DBGFR3AddrFromFlat(pVM, &Addr, orig_addr), &off, &Sym, NULL /*phMod*/);
+ int rc = DBGFR3AsSymbolByAddr(pVM->pUVM, DBGF_AS_GLOBAL, DBGFR3AddrFromFlat(pVM->pUVM, &Addr, orig_addr),
+ RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, &off, &Sym, NULL /*phMod*/);
if (RT_SUCCESS(rc))
{
static char szSym[sizeof(Sym.szName) + 48];
@@ -4442,7 +4474,7 @@ int cpu_get_pic_interrupt(CPUX86State *env)
u8Interrupt, rc, env->segs[R_CS].selector, (uint64_t)env->eip, (uint64_t)env->eflags));
if (RT_SUCCESS(rc))
{
- if (VMCPU_FF_ISPENDING(env->pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
+ if (VMCPU_FF_IS_PENDING(env->pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))
env->interrupt_request |= CPU_INTERRUPT_HARD;
return u8Interrupt;
}
@@ -4463,7 +4495,7 @@ void cpu_set_apic_base(CPUX86State *env, uint64_t val)
uint64_t cpu_get_apic_base(CPUX86State *env)
{
uint64_t u64;
- int rc = PDMApicGetBase(env->pVM, &u64);
+ int rc = CPUMQueryGuestMsr(env->pVCpu, MSR_IA32_APICBASE, &u64);
if (RT_SUCCESS(rc))
{
LogFlow(("cpu_get_apic_base: returns %#llx \n", u64));
@@ -4482,7 +4514,7 @@ void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
uint8_t cpu_get_apic_tpr(CPUX86State *env)
{
uint8_t u8;
- int rc = PDMApicGetTPR(env->pVCpu, &u8, NULL);
+ int rc = PDMApicGetTPR(env->pVCpu, &u8, NULL, NULL);
if (RT_SUCCESS(rc))
{
LogFlow(("cpu_get_apic_tpr: returns %#x\n", u8));
@@ -4534,7 +4566,7 @@ void cpu_outb(CPUX86State *env, pio_addr_t addr, uint8_t val)
if (addr != 0x80 && addr != 0x70 && addr != 0x61)
Log2(("cpu_outb: addr=%#06x val=%#x\n", addr, val));
- rc = IOMIOPortWrite(env->pVM, (RTIOPORT)addr, val, 1);
+ rc = IOMIOPortWrite(env->pVM, env->pVCpu, (RTIOPORT)addr, val, 1);
if (RT_LIKELY(rc == VINF_SUCCESS))
return;
if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
@@ -4549,7 +4581,7 @@ void cpu_outb(CPUX86State *env, pio_addr_t addr, uint8_t val)
void cpu_outw(CPUX86State *env, pio_addr_t addr, uint16_t val)
{
//Log2(("cpu_outw: addr=%#06x val=%#x\n", addr, val));
- int rc = IOMIOPortWrite(env->pVM, (RTIOPORT)addr, val, 2);
+ int rc = IOMIOPortWrite(env->pVM, env->pVCpu, (RTIOPORT)addr, val, 2);
if (RT_LIKELY(rc == VINF_SUCCESS))
return;
if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
@@ -4565,7 +4597,7 @@ void cpu_outl(CPUX86State *env, pio_addr_t addr, uint32_t val)
{
int rc;
Log2(("cpu_outl: addr=%#06x val=%#x\n", addr, val));
- rc = IOMIOPortWrite(env->pVM, (RTIOPORT)addr, val, 4);
+ rc = IOMIOPortWrite(env->pVM, env->pVCpu, (RTIOPORT)addr, val, 4);
if (RT_LIKELY(rc == VINF_SUCCESS))
return;
if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
@@ -4580,7 +4612,7 @@ void cpu_outl(CPUX86State *env, pio_addr_t addr, uint32_t val)
uint8_t cpu_inb(CPUX86State *env, pio_addr_t addr)
{
uint32_t u32 = 0;
- int rc = IOMIOPortRead(env->pVM, (RTIOPORT)addr, &u32, 1);
+ int rc = IOMIOPortRead(env->pVM, env->pVCpu, (RTIOPORT)addr, &u32, 1);
if (RT_LIKELY(rc == VINF_SUCCESS))
{
if (/*addr != 0x61 && */addr != 0x71)
@@ -4600,7 +4632,7 @@ uint8_t cpu_inb(CPUX86State *env, pio_addr_t addr)
uint16_t cpu_inw(CPUX86State *env, pio_addr_t addr)
{
uint32_t u32 = 0;
- int rc = IOMIOPortRead(env->pVM, (RTIOPORT)addr, &u32, 2);
+ int rc = IOMIOPortRead(env->pVM, env->pVCpu, (RTIOPORT)addr, &u32, 2);
if (RT_LIKELY(rc == VINF_SUCCESS))
{
Log2(("cpu_inw: addr=%#06x -> %#x\n", addr, u32));
@@ -4619,11 +4651,9 @@ uint16_t cpu_inw(CPUX86State *env, pio_addr_t addr)
uint32_t cpu_inl(CPUX86State *env, pio_addr_t addr)
{
uint32_t u32 = 0;
- int rc = IOMIOPortRead(env->pVM, (RTIOPORT)addr, &u32, 4);
+ int rc = IOMIOPortRead(env->pVM, env->pVCpu, (RTIOPORT)addr, &u32, 4);
if (RT_LIKELY(rc == VINF_SUCCESS))
{
-//if (addr==0x01f0 && u32 == 0x6b6d)
-// loglevel = ~0;
Log2(("cpu_inl: addr=%#06x -> %#x\n", addr, u32));
return u32;
}
diff --git a/src/recompiler/cpu-defs.h b/src/recompiler/cpu-defs.h
index a6b331ff..65d57063 100644
--- a/src/recompiler/cpu-defs.h
+++ b/src/recompiler/cpu-defs.h
@@ -76,7 +76,7 @@ typedef uint64_t target_ulong;
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
#ifdef VBOX
# define EXCP_EXECUTE_RAW 0x11024 /**< execute raw mode. */
-# define EXCP_EXECUTE_HWACC 0x11025 /**< execute hardware accelerated raw mode. */
+# define EXCP_EXECUTE_HM 0x11025 /**< execute hardware accelerated raw mode. */
# define EXCP_SINGLE_INSTR 0x11026 /**< executed single instruction. */
# define EXCP_RC 0x11027 /**< a EM rc was raised (VMR3Reset/Suspend/PowerOff). */
#endif /* VBOX */
diff --git a/src/recompiler/cpu-exec.c b/src/recompiler/cpu-exec.c
index 52ee778b..aa1826c4 100644
--- a/src/recompiler/cpu-exec.c
+++ b/src/recompiler/cpu-exec.c
@@ -344,10 +344,18 @@ int cpu_exec(CPUState *env1)
Log(("do_interrupt: vec=%#x int=%d pc=%04x:%RGv\n", env->exception_index, env->exception_is_int,
env->segs[R_CS].selector, (RTGCPTR)env->exception_next_eip));
# endif /* VBOX */
+# ifdef IEM_VERIFICATION_MODE /* Ugly hack*/
+ do_interrupt(env->exception_index,
+ env->exception_is_int && env->exception_is_int != 0x42,
+ env->error_code,
+ env->exception_next_eip,
+ env->exception_is_int == 0x42);
+# else
do_interrupt(env->exception_index,
env->exception_is_int,
env->error_code,
env->exception_next_eip, 0);
+# endif
/* successfully delivered */
env->old_exception = -1;
# ifdef VBOX
@@ -436,7 +444,7 @@ int cpu_exec(CPUState *env1)
if ( !(interrupt_request & CPU_INTERRUPT_HARD)
|| !(env->eflags & IF_MASK)
|| (env->hflags & HF_INHIBIT_IRQ_MASK)
- || (env->state & CPU_RAW_HWACC)
+ || (env->state & CPU_RAW_HM)
)
{
env->exception_index = ret = EXCP_SINGLE_INSTR;
diff --git a/src/recompiler/exec.c b/src/recompiler/exec.c
index 7ecade99..6ff9f985 100644
--- a/src/recompiler/exec.c
+++ b/src/recompiler/exec.c
@@ -505,7 +505,7 @@ static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
#endif
#ifdef VBOX /* We don't need such huge codegen buffer size, as execute
- most of the code in raw or hwacc mode. */
+ most of the code in raw or hm mode. */
#define DEFAULT_CODE_GEN_BUFFER_SIZE (8 * 1024 * 1024)
#else /* !VBOX */
#define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024)
diff --git a/src/recompiler/target-i386/cpu.h b/src/recompiler/target-i386/cpu.h
index b5159bf9..2adbd869 100644
--- a/src/recompiler/target-i386/cpu.h
+++ b/src/recompiler/target-i386/cpu.h
@@ -65,6 +65,7 @@
# include <VBox/vmm/vmm.h>
# include <VBox/vmm/stam.h>
# include <VBox/vmm/cpumctx.h>
+# undef MSR_IA32_APICBASE_BSP
#endif /* VBOX */
#define R_EAX 0
@@ -115,6 +116,10 @@
#define DESC_W_MASK (1 << 9) /* data: writable */
#define DESC_TSS_BUSY_MASK (1 << 9)
+#ifdef VBOX
+# define DESC_INTEL_UNUSABLE RT_BIT_32(16+8) /**< Internal VT-x bit for NULL sectors. */
+# define DESC_RAW_FLAG_BITS UINT32_C(0x00ffffff) /**< Flag bits we load from the descriptor. */
+#endif
/* eflags masks */
#define CC_C 0x0001
@@ -909,7 +914,7 @@ typedef struct CPUX86State_Ver16 {
# define CPU_RAW_RING0 0x0002 /* Set after first time RawR0 is executed, never cleared. */
# define CPU_EMULATE_SINGLE_INSTR 0x0040 /* Execute a single instruction in emulation mode */
# define CPU_EMULATE_SINGLE_STEP 0x0080 /* go into single step mode */
-# define CPU_RAW_HWACC 0x0100 /* Set after first time HWACC is executed, never cleared. */
+# define CPU_RAW_HM 0x0100 /* Set after first time HWACC is executed, never cleared. */
/** @} */
#endif /* !VBOX */
@@ -930,11 +935,19 @@ void cpu_set_ferr(CPUX86State *s);
/* this function must always be used to load data in the segment
cache: it synchronizes the hflags with the segment cache values */
+#ifndef VBOX
static inline void cpu_x86_load_seg_cache(CPUX86State *env,
int seg_reg, unsigned int selector,
target_ulong base,
unsigned int limit,
unsigned int flags)
+#else
+static inline void cpu_x86_load_seg_cache_with_clean_flags(CPUX86State *env,
+ int seg_reg, unsigned int selector,
+ target_ulong base,
+ unsigned int limit,
+ unsigned int flags)
+#endif
{
SegmentCache *sc;
unsigned int new_hflags;
@@ -943,12 +956,8 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
sc->selector = selector;
sc->base = base;
sc->limit = limit;
-#ifndef VBOX
- sc->flags = flags;
-#else
- if (flags & DESC_P_MASK)
- flags |= DESC_A_MASK; /* Make sure the A bit is set to avoid trouble. */
sc->flags = flags;
+#ifdef VBOX
sc->newselector = 0;
sc->fVBoxFlags = CPUMSELREG_FLAGS_VALID;
#endif
@@ -995,6 +1004,23 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
}
}
+#ifdef VBOX
+/* Raw input, adjust the flags adding the stupid intel flag when applicable. */
+static inline void cpu_x86_load_seg_cache(CPUX86State *env,
+ int seg_reg, unsigned int selector,
+ target_ulong base,
+ unsigned int limit,
+ unsigned int flags)
+{
+ flags &= DESC_RAW_FLAG_BITS;
+ if (flags & DESC_P_MASK)
+ flags |= DESC_A_MASK; /* Make sure the A bit is set to avoid trouble. */
+ else if (selector < 4U)
+ flags |= DESC_INTEL_UNUSABLE;
+ cpu_x86_load_seg_cache_with_clean_flags(env, seg_reg, selector, base, limit, flags);
+}
+#endif
+
static inline void cpu_x86_load_seg_cache_sipi(CPUX86State *env,
int sipi_vector)
{
diff --git a/src/recompiler/target-i386/op_helper.c b/src/recompiler/target-i386/op_helper.c
index 048c6865..20d671cd 100644
--- a/src/recompiler/target-i386/op_helper.c
+++ b/src/recompiler/target-i386/op_helper.c
@@ -229,15 +229,6 @@ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
int index;
target_ulong ptr;
-#ifdef VBOX
- /* Trying to load a selector with CPL=1? */
- if ((env->hflags & HF_CPL_MASK) == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0))
- {
- Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
- selector = selector & 0xfffc;
- }
-#endif /* VBOX */
-
if (selector & 0x4)
dt = &env->ldt;
else
@@ -269,8 +260,10 @@ static inline void load_seg_cache_raw_dt(SegmentCache *sc, uint32_t e1, uint32_t
{
sc->base = get_seg_base(e1, e2);
sc->limit = get_seg_limit(e1, e2);
+#ifndef VBOX
sc->flags = e2;
-#ifdef VBOX
+#else
+ sc->flags = e2 & DESC_RAW_FLAG_BITS;
sc->newselector = 0;
sc->fVBoxFlags = CPUMSELREG_FLAGS_VALID;
#endif
@@ -344,7 +337,7 @@ static void tss_load_seg(int seg_reg, int selector)
/* Trying to load a selector with CPL=1? */
if (cpl == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0))
{
- Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
+ Log(("RPL 1 -> sel %04X -> %04X (tss_load_seg)\n", selector, selector & 0xfffc));
selector = selector & 0xfffc;
}
#endif /* VBOX */
@@ -458,6 +451,7 @@ static void switch_tss(int tss_selector,
else
old_tss_limit_max = 43;
+#ifndef VBOX /* The old TSS is written first... */
/* read all the registers from the new TSS */
if (type & 8) {
/* 32 bit */
@@ -484,6 +478,7 @@ static void switch_tss(int tss_selector,
new_segs[R_GS] = 0;
new_trap = 0;
}
+#endif
/* NOTE: we must avoid memory exceptions during the task switch,
so we make dummy accesses before */
@@ -523,10 +518,6 @@ static void switch_tss(int tss_selector,
stl_kernel(env->tr.base + (0x28 + 7 * 4), EDI);
for(i = 0; i < 6; i++)
stw_kernel(env->tr.base + (0x48 + i * 4), env->segs[i].selector);
-#ifdef VBOX
- /* Must store the ldt as it gets reloaded and might have been changed. */
- stw_kernel(env->tr.base + 0x60, env->ldt.selector);
-#endif
#if defined(VBOX) && defined(DEBUG)
printf("TSS 32 bits switch\n");
printf("Saving CS=%08X\n", env->segs[R_CS].selector);
@@ -544,12 +535,37 @@ static void switch_tss(int tss_selector,
stw_kernel(env->tr.base + (0x12 + 6 * 2), ESI);
stw_kernel(env->tr.base + (0x12 + 7 * 2), EDI);
for(i = 0; i < 4; i++)
- stw_kernel(env->tr.base + (0x22 + i * 4), env->segs[i].selector);
+ stw_kernel(env->tr.base + (0x22 + i * 2), env->segs[i].selector);
+ }
+
#ifdef VBOX
- /* Must store the ldt as it gets reloaded and might have been changed. */
- stw_kernel(env->tr.base + 0x2a, env->ldt.selector);
-#endif
+ /* read all the registers from the new TSS - may be the same as the old one */
+ if (type & 8) {
+ /* 32 bit */
+ new_cr3 = ldl_kernel(tss_base + 0x1c);
+ new_eip = ldl_kernel(tss_base + 0x20);
+ new_eflags = ldl_kernel(tss_base + 0x24);
+ for(i = 0; i < 8; i++)
+ new_regs[i] = ldl_kernel(tss_base + (0x28 + i * 4));
+ for(i = 0; i < 6; i++)
+ new_segs[i] = lduw_kernel(tss_base + (0x48 + i * 4));
+ new_ldt = lduw_kernel(tss_base + 0x60);
+ new_trap = ldl_kernel(tss_base + 0x64);
+ } else {
+ /* 16 bit */
+ new_cr3 = 0;
+ new_eip = lduw_kernel(tss_base + 0x0e);
+ new_eflags = lduw_kernel(tss_base + 0x10);
+ for(i = 0; i < 8; i++)
+ new_regs[i] = lduw_kernel(tss_base + (0x12 + i * 2)) | 0xffff0000;
+ for(i = 0; i < 4; i++)
+ new_segs[i] = lduw_kernel(tss_base + (0x22 + i * 2));
+ new_ldt = lduw_kernel(tss_base + 0x2a);
+ new_segs[R_FS] = 0;
+ new_segs[R_GS] = 0;
+ new_trap = 0;
}
+#endif
/* now if an exception occurs, it will occurs in the next task
context */
@@ -576,8 +592,10 @@ static void switch_tss(int tss_selector,
env->tr.selector = tss_selector;
env->tr.base = tss_base;
env->tr.limit = tss_limit;
+#ifndef VBOX
env->tr.flags = e2 & ~DESC_TSS_BUSY_MASK;
-#ifdef VBOX
+#else
+ env->tr.flags = e2 & (DESC_RAW_FLAG_BITS & ~(DESC_TSS_BUSY_MASK)); /** @todo stop clearing the busy bit, VT-x and AMD-V seems to set it in the hidden bits. */
env->tr.fVBoxFlags = CPUMSELREG_FLAGS_VALID;
env->tr.newselector = 0;
#endif
@@ -621,6 +639,7 @@ static void switch_tss(int tss_selector,
env->ldt.limit = 0;
env->ldt.flags = 0;
#ifdef VBOX
+ env->ldt.flags = DESC_INTEL_UNUSABLE;
env->ldt.fVBoxFlags = CPUMSELREG_FLAGS_VALID;
env->ldt.newselector = 0;
#endif
@@ -955,6 +974,10 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
if (load_segment(&e1, &e2, selector) != 0)
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
+#ifdef VBOX /** @todo figure out when this is done one day... */
+ if (!(e2 & DESC_A_MASK))
+ e2 = set_segment_accessed(selector, e2);
+#endif
if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
@@ -971,6 +994,10 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
if (load_segment(&ss_e1, &ss_e2, ss) != 0)
raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
+#ifdef VBOX /** @todo figure out when this is done one day... */
+ if (!(ss_e2 & DESC_A_MASK))
+ ss_e2 = set_segment_accessed(ss, ss_e2);
+#endif
ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
if (ss_dpl != dpl)
raise_exception_err(EXCP0A_TSS, ss & 0xfffc);
@@ -1323,7 +1350,11 @@ static void do_interrupt64(int intno, int is_int, int error_code,
if (new_stack) {
ss = 0 | dpl;
+#ifndef VBOX
cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0);
+#else
+ cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, dpl << DESC_DPL_SHIFT);
+#endif
}
ESP = esp;
@@ -1743,10 +1774,11 @@ static int check_exception(int intno, int *error_code)
# ifndef VBOX
qemu_system_reset_request();
+ return EXCP_HLT;
# else
- remR3RaiseRC(env->pVM, VINF_EM_RESET); /** @todo test + improve tripple fault handling. */
+ remR3RaiseRC(env->pVM, VINF_EM_TRIPLE_FAULT);
+ return EXCP_RC;
# endif
- return EXCP_HLT;
}
#endif
@@ -2500,6 +2532,7 @@ void helper_lldt(int selector)
env->ldt.base = 0;
env->ldt.limit = 0;
#ifdef VBOX
+ env->ldt.flags = DESC_INTEL_UNUSABLE;
env->ldt.fVBoxFlags = CPUMSELREG_FLAGS_VALID;
env->ldt.newselector = 0;
#endif
@@ -2555,19 +2588,19 @@ void helper_ltr(int selector)
target_ulong ptr;
#ifdef VBOX
- Log(("helper_ltr: old tr=%RTsel {.base=%RGv, .limit=%RGv, .flags=%RX32} new=%RTsel\n",
- (RTSEL)env->tr.selector, (RTGCPTR)env->tr.base, (RTGCPTR)env->tr.limit,
+ Log(("helper_ltr: pc=%RGv old tr=%RTsel {.base=%RGv, .limit=%RGv, .flags=%RX32} new=%RTsel\n",
+ (RTGCPTR)env->eip, (RTSEL)env->tr.selector, (RTGCPTR)env->tr.base, (RTGCPTR)env->tr.limit,
env->tr.flags, (RTSEL)(selector & 0xffff)));
#endif
selector &= 0xffff;
if ((selector & 0xfffc) == 0) {
/* NULL selector case: invalid TR */
+#ifdef VBOX
+ raise_exception_err(EXCP0A_TSS, 0);
+#else
env->tr.base = 0;
env->tr.limit = 0;
env->tr.flags = 0;
-#ifdef VBOX
- env->tr.fVBoxFlags = CPUMSELREG_FLAGS_VALID;
- env->tr.newselector = 0;
#endif
} else {
if (selector & 0x4)
@@ -2636,12 +2669,13 @@ void helper_load_seg(int seg_reg, int selector)
/* Trying to load a selector with CPL=1? */
if (cpl == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0))
{
- Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
+ Log(("RPL 1 -> sel %04X -> %04X (helper_load_seg)\n", selector, selector & 0xfffc));
selector = selector & 0xfffc;
}
#endif /* VBOX */
if ((selector & 0xfffc) == 0) {
/* null selector case */
+#ifndef VBOX
if (seg_reg == R_SS
#ifdef TARGET_X86_64
&& (!(env->hflags & HF_CS64_MASK) || cpl == 3)
@@ -2649,6 +2683,16 @@ void helper_load_seg(int seg_reg, int selector)
)
raise_exception_err(EXCP0D_GPF, 0);
cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
+#else
+ if (seg_reg == R_SS) {
+ if (!(env->hflags & HF_CS64_MASK) || cpl == 3)
+ raise_exception_err(EXCP0D_GPF, 0);
+ e2 = (cpl << DESC_DPL_SHIFT) | DESC_INTEL_UNUSABLE;
+ } else {
+ e2 = DESC_INTEL_UNUSABLE;
+ }
+ cpu_x86_load_seg_cache_with_clean_flags(env, seg_reg, selector, 0, 0, e2);
+#endif
} else {
if (selector & 0x4)
@@ -2746,6 +2790,10 @@ void helper_ljmp_protected(int new_cs, target_ulong new_eip,
if (new_eip > limit &&
!(env->hflags & HF_LMA_MASK) && !(e2 & DESC_L_MASK))
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
+#ifdef VBOX
+ if (!(e2 & DESC_A_MASK))
+ e2 = set_segment_accessed(new_cs, e2);
+#endif
cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,
get_seg_base(e1, e2), limit, e2);
EIP = new_eip;
@@ -2871,6 +2919,10 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
}
if (!(e2 & DESC_P_MASK))
raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
+#ifdef VBOX
+ if (!(e2 & DESC_A_MASK))
+ e2 = set_segment_accessed(new_cs, e2);
+#endif
#ifdef TARGET_X86_64
/* XXX: check 16/32 bit cases in long mode */
@@ -3168,11 +3220,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
new_cs &= 0xffff;
if (is_iret) {
POPL(ssp, sp, sp_mask, new_eflags);
+#define LOG_GROUP LOG_GROUP_REM
#if defined(VBOX) && defined(DEBUG)
- printf("iret: new CS %04X\n", new_cs);
- printf("iret: new EIP %08X\n", (uint32_t)new_eip);
- printf("iret: new EFLAGS %08X\n", new_eflags);
- printf("iret: EAX=%08x\n", (uint32_t)EAX);
+ Log(("iret: new CS %04X (old=%x)\n", new_cs, env->segs[R_CS].selector));
+ Log(("iret: new EIP %08X\n", (uint32_t)new_eip));
+ Log(("iret: new EFLAGS %08X\n", new_eflags));
+ Log(("iret: EAX=%08x\n", (uint32_t)EAX));
#endif
if (new_eflags & VM_MASK)
goto return_to_vm86;
@@ -3180,10 +3233,22 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
#ifdef VBOX
if ((new_cs & 0x3) == 1 && (env->state & CPU_RAW_RING0))
{
-# ifdef DEBUG
- printf("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc);
-# endif
- new_cs = new_cs & 0xfffc;
+ if ( !EMIsRawRing1Enabled(env->pVM)
+ || env->segs[R_CS].selector == (new_cs & 0xfffc))
+ {
+ Log(("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc));
+ new_cs = new_cs & 0xfffc;
+ }
+ else
+ {
+ /* Ugly assumption: assume a genuine switch to ring-1. */
+ Log(("Genuine switch to ring-1 (iret)\n"));
+ }
+ }
+ else if ((new_cs & 0x3) == 2 && (env->state & CPU_RAW_RING0) && EMIsRawRing1Enabled(env->pVM))
+ {
+ Log(("RPL 2 -> new_cs %04X -> %04X\n", new_cs, (new_cs & 0xfffc) | 1));
+ new_cs = (new_cs & 0xfffc) | 1;
}
#endif
} else {
@@ -3199,14 +3264,14 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
if ((new_cs & 0xfffc) == 0)
{
#if defined(VBOX) && defined(DEBUG)
- printf("new_cs & 0xfffc) == 0\n");
+ Log(("new_cs & 0xfffc) == 0\n"));
#endif
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
}
if (load_segment(&e1, &e2, new_cs) != 0)
{
#if defined(VBOX) && defined(DEBUG)
- printf("load_segment failed\n");
+ Log(("load_segment failed\n"));
#endif
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
}
@@ -3214,7 +3279,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
!(e2 & DESC_CS_MASK))
{
#if defined(VBOX) && defined(DEBUG)
- printf("e2 mask %08x\n", e2);
+ Log(("e2 mask %08x\n", e2));
#endif
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
}
@@ -3223,16 +3288,17 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
if (rpl < cpl)
{
#if defined(VBOX) && defined(DEBUG)
- printf("rpl < cpl (%d vs %d)\n", rpl, cpl);
+ Log(("rpl < cpl (%d vs %d)\n", rpl, cpl));
#endif
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
+
if (e2 & DESC_C_MASK) {
if (dpl > rpl)
{
#if defined(VBOX) && defined(DEBUG)
- printf("dpl > rpl (%d vs %d)\n", dpl, rpl);
+ Log(("dpl > rpl (%d vs %d)\n", dpl, rpl));
#endif
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
}
@@ -3240,7 +3306,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
if (dpl != rpl)
{
#if defined(VBOX) && defined(DEBUG)
- printf("dpl != rpl (%d vs %d) e1=%x e2=%x\n", dpl, rpl, e1, e2);
+ Log(("dpl != rpl (%d vs %d) e1=%x e2=%x\n", dpl, rpl, e1, e2));
#endif
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
}
@@ -3248,7 +3314,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
if (!(e2 & DESC_P_MASK))
{
#if defined(VBOX) && defined(DEBUG)
- printf("DESC_P_MASK e2=%08x\n", e2);
+ Log(("DESC_P_MASK e2=%08x\n", e2));
#endif
raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
}
@@ -3289,12 +3355,9 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
if ((new_ss & 0xfffc) == 0) {
#ifdef TARGET_X86_64
/* NULL ss is allowed in long mode if cpl != 3*/
+# ifndef VBOX
/* XXX: test CS64 ? */
if ((env->hflags & HF_LMA_MASK) && rpl != 3) {
-# ifdef VBOX
- if (!(e2 & DESC_A_MASK))
- e2 = set_segment_accessed(new_cs, e2);
-# endif
cpu_x86_load_seg_cache(env, R_SS, new_ss,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
@@ -3302,24 +3365,62 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
DESC_W_MASK | DESC_A_MASK);
ss_e2 = DESC_B_MASK; /* XXX: should not be needed ? */
} else
+# else /* VBOX */
+ if ((env->hflags & HF_LMA_MASK) && rpl != 3 && (e2 & DESC_L_MASK)) {
+ if (!(e2 & DESC_A_MASK))
+ e2 = set_segment_accessed(new_cs, e2);
+ cpu_x86_load_seg_cache_with_clean_flags(env, R_SS, new_ss,
+ 0, 0xffffffff,
+ DESC_INTEL_UNUSABLE | (rpl << DESC_DPL_SHIFT) );
+ ss_e2 = DESC_B_MASK; /* not really used */
+ } else
+# endif
#endif
{
+#if defined(VBOX) && defined(DEBUG)
+ Log(("NULL ss, rpl=%d\n", rpl));
+#endif
raise_exception_err(EXCP0D_GPF, 0);
}
} else {
if ((new_ss & 3) != rpl)
+ {
+#if defined(VBOX) && defined(DEBUG)
+ Log(("new_ss=%x != rpl=%d\n", new_ss, rpl));
+#endif
raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
+ }
if (load_segment(&ss_e1, &ss_e2, new_ss) != 0)
+ {
+#if defined(VBOX) && defined(DEBUG)
+ Log(("new_ss=%x load error\n", new_ss));
+#endif
raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
+ }
if (!(ss_e2 & DESC_S_MASK) ||
(ss_e2 & DESC_CS_MASK) ||
!(ss_e2 & DESC_W_MASK))
+ {
+#if defined(VBOX) && defined(DEBUG)
+ Log(("new_ss=%x ss_e2=%#x bad type\n", new_ss, ss_e2));
+#endif
raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
+ }
dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;
if (dpl != rpl)
+ {
+#if defined(VBOX) && defined(DEBUG)
+ Log(("SS.dpl=%u != rpl=%u\n", dpl, rpl));
+#endif
raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
+ }
if (!(ss_e2 & DESC_P_MASK))
+ {
+#if defined(VBOX) && defined(DEBUG)
+ Log(("new_ss=%#x #NP\n", new_ss));
+#endif
raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc);
+ }
#ifdef VBOX
if (!(e2 & DESC_A_MASK))
e2 = set_segment_accessed(new_cs, e2);
@@ -3402,6 +3503,7 @@ void helper_iret_protected(int shift, int next_eip)
uint32_t e1, e2;
#ifdef VBOX
+ Log(("iret (shift=%d new_eip=%#x)\n", shift, next_eip));
e1 = e2 = 0; /** @todo Why do we do this? */
remR3TrapClear(env->pVM);
#endif
@@ -3410,7 +3512,12 @@ void helper_iret_protected(int shift, int next_eip)
if (env->eflags & NT_MASK) {
#ifdef TARGET_X86_64
if (env->hflags & HF_LMA_MASK)
+ {
+#if defined(VBOX) && defined(DEBUG)
+ Log(("eflags.NT=1 on iret in long mode\n"));
+#endif
raise_exception_err(EXCP0D_GPF, 0);
+ }
#endif
tss_selector = lduw_kernel(env->tr.base + 0);
if (tss_selector & 4)
@@ -3580,14 +3687,31 @@ void helper_movl_drN_T0(int reg, target_ulong t0)
hw_breakpoint_remove(env, reg);
env->dr[reg] = t0;
hw_breakpoint_insert(env, reg);
+# ifndef VBOX
} else if (reg == 7) {
+# else
+ } else if (reg == 7 || reg == 5) { /* (DR5 is an alias for DR7.) */
+ if (t0 & X86_DR7_MBZ_MASK)
+ raise_exception_err(EXCP0D_GPF, 0);
+ t0 |= X86_DR7_RA1_MASK;
+ t0 &= ~X86_DR7_RAZ_MASK;
+# endif
for (i = 0; i < 4; i++)
hw_breakpoint_remove(env, i);
env->dr[7] = t0;
for (i = 0; i < 4; i++)
hw_breakpoint_insert(env, i);
- } else
+ } else {
+# ifndef VBOX
env->dr[reg] = t0;
+# else
+ if (t0 & X86_DR6_MBZ_MASK)
+ raise_exception_err(EXCP0D_GPF, 0);
+ t0 |= X86_DR6_RA1_MASK;
+ t0 &= ~X86_DR6_RAZ_MASK;
+ env->dr[6] = t0; /* (DR4 is an alias for DR6.) */
+# endif
+ }
}
#endif
@@ -4067,7 +4191,11 @@ target_ulong helper_lar(target_ulong selector1)
}
}
CC_SRC = eflags | CC_Z;
+#ifdef VBOX /* AMD says 0x00ffff00, while intel says 0x00fxff00. Bochs and IEM does like AMD says (x=f). */
+ return e2 & 0x00ffff00;
+#else
return e2 & 0x00f0ff00;
+#endif
}
void helper_verr(target_ulong selector1)
@@ -6632,7 +6760,7 @@ void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
break;
}
#else /* VBOX */
- AssertMsgFailed(("We shouldn't be here, HWACCM supported differently!"));
+ AssertMsgFailed(("We shouldn't be here, HM supported differently!"));
#endif /* VBOX */
}
diff --git a/src/recompiler/target-i386/translate.c b/src/recompiler/target-i386/translate.c
index 5adf907c..46bf8208 100644
--- a/src/recompiler/target-i386/translate.c
+++ b/src/recompiler/target-i386/translate.c
@@ -106,7 +106,9 @@ uint8_t ldub_code_raw(target_ulong pc)
{
uint8_t b;
+# ifdef VBOX_WITH_RAW_MODE
if (!remR3GetOpcode(cpu_single_env, pc, &b))
+# endif
b = ldub_code(pc);
return b;
}