diff options
Diffstat (limited to 'src/recompiler')
-rw-r--r-- | src/recompiler/Makefile.kmk | 12 | ||||
-rw-r--r-- | src/recompiler/Sun/config-host.h | 2 | ||||
-rw-r--r-- | src/recompiler/Sun/config.h | 2 | ||||
-rw-r--r-- | src/recompiler/Sun/crt/stdio.h | 2 | ||||
-rw-r--r-- | src/recompiler/Sun/deftoimp.sed | 2 | ||||
-rw-r--r-- | src/recompiler/VBoxREM.def | 2 | ||||
-rw-r--r-- | src/recompiler/VBoxREMWrapper.cpp | 36 | ||||
-rw-r--r-- | src/recompiler/VBoxREMWrapperA.asm | 2 | ||||
-rw-r--r-- | src/recompiler/VBoxRecompiler.c | 458 | ||||
-rw-r--r-- | src/recompiler/cpu-defs.h | 2 | ||||
-rw-r--r-- | src/recompiler/cpu-exec.c | 10 | ||||
-rw-r--r-- | src/recompiler/exec.c | 2 | ||||
-rw-r--r-- | src/recompiler/target-i386/cpu.h | 38 | ||||
-rw-r--r-- | src/recompiler/target-i386/op_helper.c | 226 | ||||
-rw-r--r-- | src/recompiler/target-i386/translate.c | 2 |
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; } |