diff options
author | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2013-01-24 21:11:05 +0000 |
---|---|---|
committer | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2013-01-24 21:11:05 +0000 |
commit | ec5966c968d314ec776c12f7a60ba1aeacebf35f (patch) | |
tree | 1d89d4fec05f4fd8c1bb1a96af924ecb70c84b8e /src | |
parent | a7fa3e1d2eb185d8ba4c0b6b87a27331610a4af2 (diff) | |
download | VirtualBox-svn-ec5966c968d314ec776c12f7a60ba1aeacebf35f.tar.gz |
PATM: Changed two Main APIs to use PUVM instead of PVM (one of them directly accessed it). Lot's of function scope cleanups.
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@44362 cfe28804-0f27-0410-a406-dd0f0b0b656f
Diffstat (limited to 'src')
-rw-r--r-- | src/VBox/Main/src-client/MachineDebuggerImpl.cpp | 21 | ||||
-rw-r--r-- | src/VBox/VMM/VMMAll/PATMAll.cpp | 31 | ||||
-rw-r--r-- | src/VBox/VMM/VMMAll/TRPMAll.cpp | 2 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/CPUM.cpp | 2 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/CSAM.cpp | 34 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/EM.cpp | 2 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/EMRaw.cpp | 2 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/HM.cpp | 4 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/PATM.cpp | 282 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/PATMGuest.cpp | 4 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/PATMPatch.cpp | 24 | ||||
-rw-r--r-- | src/VBox/VMM/VMMR3/PATMSSM.cpp | 4 | ||||
-rw-r--r-- | src/VBox/VMM/VMMRC/CSAMRC.cpp | 4 | ||||
-rw-r--r-- | src/VBox/VMM/VMMRC/PATMRC.cpp | 12 | ||||
-rw-r--r-- | src/VBox/VMM/VMMRC/PDMRCDevice.cpp | 2 | ||||
-rw-r--r-- | src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp | 2 | ||||
-rw-r--r-- | src/VBox/VMM/include/EMHandleRCTmpl.h | 2 | ||||
-rw-r--r-- | src/VBox/VMM/include/PATMInternal.h | 187 | ||||
-rw-r--r-- | src/recompiler/VBoxREMWrapper.cpp | 7 |
19 files changed, 246 insertions, 382 deletions
diff --git a/src/VBox/Main/src-client/MachineDebuggerImpl.cpp b/src/VBox/Main/src-client/MachineDebuggerImpl.cpp index 37e428b6c84..c9e187ea4fc 100644 --- a/src/VBox/Main/src-client/MachineDebuggerImpl.cpp +++ b/src/VBox/Main/src-client/MachineDebuggerImpl.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2010 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; @@ -296,14 +296,14 @@ STDMETHODIMP MachineDebugger::COMGETTER(PATMEnabled) (BOOL *aEnabled) CheckComArgOutPointerValid(aEnabled); AutoCaller autoCaller(this); - if (FAILED(autoCaller.rc())) return autoCaller.rc(); + if (FAILED(autoCaller.rc())) + return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); - Console::SafeVMPtrQuiet pVM (mParent); - - if (pVM.isOk()) - *aEnabled = PATMIsEnabled (pVM.raw()); + Console::SafeVMPtrQuiet ptrVM(mParent); + if (ptrVM.isOk()) + *aEnabled = PATMR3IsEnabled (ptrVM.rawUVM()); else *aEnabled = false; @@ -332,10 +332,13 @@ STDMETHODIMP MachineDebugger::COMSETTER(PATMEnabled) (BOOL aEnable) return S_OK; } - Console::SafeVMPtr pVM(mParent); - if (FAILED(pVM.rc())) return pVM.rc(); + Console::SafeVMPtr ptrVM(mParent); + if (FAILED(ptrVM.rc())) + return ptrVM.rc(); - PATMR3AllowPatching (pVM, aEnable); + int vrc = PATMR3AllowPatching(ptrVM.rawUVM(), RT_BOOL(aEnable)); + if (RT_FAILURE(vrc)) + return setError(VBOX_E_VM_ERROR, tr("PATMR3AllowPatching returned %Rrc"), vrc); return S_OK; } diff --git a/src/VBox/VMM/VMMAll/PATMAll.cpp b/src/VBox/VMM/VMMAll/PATMAll.cpp index 55b744ed3e6..015d0c5d747 100644 --- a/src/VBox/VMM/VMMAll/PATMAll.cpp +++ b/src/VBox/VMM/VMMAll/PATMAll.cpp @@ -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; @@ -46,7 +46,7 @@ * @param pCtxCore The cpu context core. * @see pg_raw */ -VMMDECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore) +VMM_INT_DECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore) { bool fPatchCode = PATMIsPatchGCAddr(pVM, pCtxCore->eip); @@ -117,7 +117,7 @@ VMMDECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore) * @param rawRC Raw mode return code * @see @ref pg_raw */ -VMMDECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC) +VMM_INT_DECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC) { bool fPatchCode = PATMIsPatchGCAddr(pVM, pCtxCore->eip); /* @@ -157,7 +157,7 @@ VMMDECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC) Assert(enmState != PATMTRANS_OVERWRITTEN); if (enmState == PATMTRANS_SAFE) { - Assert(!PATMFindActivePatchByEntrypoint(pVM, pOrgInstrGC)); + Assert(!patmFindActivePatchByEntrypoint(pVM, pOrgInstrGC)); Log(("Switchback from %RRv to %RRv (Psp=%x)\n", pCtxCore->eip, pOrgInstrGC, CTXSUFF(pVM->patm.s.pGCState)->Psp)); STAM_COUNTER_INC(&pVM->patm.s.StatSwitchBack); pCtxCore->eip = pOrgInstrGC; @@ -209,7 +209,7 @@ VMMDECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC) * @param pVM Pointer to the VM. * @param pCtxCore The context core. */ -VMMDECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore) +VMM_INT_DECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore) { uint32_t efl = pCtxCore->eflags.u32; efl &= ~PATM_VIRTUAL_FLAGS_MASK; @@ -225,7 +225,7 @@ VMMDECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore) * @param pCtxCore The context core. * @param efl The new EFLAGS value. */ -VMMDECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl) +VMM_INT_DECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl) { pVM->patm.s.CTXSUFF(pGCState)->uVMFlags = efl & PATM_VIRTUAL_FLAGS_MASK; efl &= ~PATM_VIRTUAL_FLAGS_MASK; @@ -239,7 +239,7 @@ VMMDECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl) * @param pVM Pointer to the VM. * @param pAddrGC Guest context address */ -VMMDECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC) +VMM_INT_DECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC) { return ( PATMIsEnabled(pVM) && ((pAddrGC >= (RTRCPTR)pVM->patm.s.pPatchMemGC && pAddrGC < (RTRCPTR)((RTRCUINTPTR)pVM->patm.s.pPatchMemGC + pVM->patm.s.cbPatchMem)))) ? true : false; @@ -251,7 +251,7 @@ VMMDECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC) * @returns VBox status code. * @param pVM Pointer to the VM. */ -VMMDECL(RCPTRTYPE(PPATMGCSTATE)) PATMQueryGCState(PVM pVM) +VMM_INT_DECL(RCPTRTYPE(PPATMGCSTATE)) PATMQueryGCState(PVM pVM) { return pVM->patm.s.pGCStateGC; } @@ -262,6 +262,7 @@ VMMDECL(RCPTRTYPE(PPATMGCSTATE)) PATMQueryGCState(PVM pVM) * @returns VBox status code. * @param pVM Pointer to the VM. * @param pAddrGC Guest context address + * @internal */ VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddrGC) { @@ -276,7 +277,7 @@ VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddrGC) * @param GCPhys MMIO physical address * @param pCachedData GC pointer to cached data */ -VMMDECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData) +VMM_INT_DECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData) { pVM->patm.s.mmio.GCPhys = GCPhys; pVM->patm.s.mmio.pCachedData = (RTRCPTR)pCachedData; @@ -292,7 +293,7 @@ VMMDECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData) * * @param pVM Pointer to the VM. */ -VMMDECL(bool) PATMAreInterruptsEnabled(PVM pVM) +VMM_INT_DECL(bool) PATMAreInterruptsEnabled(PVM pVM) { PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(VMMGetCpu(pVM)); @@ -308,7 +309,7 @@ VMMDECL(bool) PATMAreInterruptsEnabled(PVM pVM) * @param pVM Pointer to the VM. * @param pCtxCore CPU context */ -VMMDECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore) +VMM_INT_DECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore) { if (PATMIsEnabled(pVM)) { @@ -326,7 +327,7 @@ VMMDECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore) * @param pInstrGC Guest context point to the instruction * */ -VMMDECL(PPATMPATCHREC) PATMQueryFunctionPatch(PVM pVM, RTRCPTR pInstrGC) +PPATMPATCHREC patmQueryFunctionPatch(PVM pVM, RTRCPTR pInstrGC) { PPATMPATCHREC pRec; @@ -350,7 +351,7 @@ VMMDECL(PPATMPATCHREC) PATMQueryFunctionPatch(PVM pVM, RTRCPTR pInstrGC) * @param pOpcode Original instruction opcode (out, optional) * @param pSize Original instruction size (out, optional) */ -VMMDECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize) +VMM_INT_DECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize) { PPATMPATCHREC pRec; @@ -449,7 +450,7 @@ end: * @param pBranchTarget Original branch target * @param pRelBranchPatch Relative duplicated function address */ -VMMDECL(int) PATMAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR pBranchTarget, RTRCUINTPTR pRelBranchPatch) +int patmAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR pBranchTarget, RTRCUINTPTR pRelBranchPatch) { PPATCHJUMPTABLE pJumpTable; @@ -515,7 +516,7 @@ VMMDECL(int) PATMAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR p * @param opcode DIS instruction opcode * @param fPatchFlags Patch flags */ -VMMDECL(const char *) patmGetInstructionString(uint32_t opcode, uint32_t fPatchFlags) +const char *patmGetInstructionString(uint32_t opcode, uint32_t fPatchFlags) { const char *pszInstr = NULL; diff --git a/src/VBox/VMM/VMMAll/TRPMAll.cpp b/src/VBox/VMM/VMMAll/TRPMAll.cpp index ae6f5922ce7..1fa647150e0 100644 --- a/src/VBox/VMM/VMMAll/TRPMAll.cpp +++ b/src/VBox/VMM/VMMAll/TRPMAll.cpp @@ -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; diff --git a/src/VBox/VMM/VMMR3/CPUM.cpp b/src/VBox/VMM/VMMR3/CPUM.cpp index c4f1d1640de..820b97a9571 100644 --- a/src/VBox/VMM/VMMR3/CPUM.cpp +++ b/src/VBox/VMM/VMMR3/CPUM.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 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; diff --git a/src/VBox/VMM/VMMR3/CSAM.cpp b/src/VBox/VMM/VMMR3/CSAM.cpp index 3c9b64bd3d7..bbda1c777db 100644 --- a/src/VBox/VMM/VMMR3/CSAM.cpp +++ b/src/VBox/VMM/VMMR3/CSAM.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -671,17 +671,18 @@ static DECLCALLBACK(int) csamr3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, /** * Convert guest context address to host context pointer * - * @returns VBox status code. + * @returns Byte pointer (ring-3 context) corresponding to pGCPtr on success, + * NULL on failure. * @param pVM Pointer to the VM. * @param pCacheRec Address conversion cache record * @param pGCPtr Guest context pointer * @returns Host context pointer or NULL in case of an error * */ -static R3PTRTYPE(void *) CSAMGCVirtToHCVirt(PVM pVM, PCSAMP2GLOOKUPREC pCacheRec, RCPTRTYPE(uint8_t *) pGCPtr) +static uint8_t *csamR3GCVirtToHCVirt(PVM pVM, PCSAMP2GLOOKUPREC pCacheRec, RCPTRTYPE(uint8_t *) pGCPtr) { int rc; - R3PTRTYPE(void *) pHCPtr; + void *pHCPtr; Assert(pVM->cCpus == 1); PVMCPU pVCpu = VMMGetCpu0(pVM); @@ -689,7 +690,7 @@ static R3PTRTYPE(void *) CSAMGCVirtToHCVirt(PVM pVM, PCSAMP2GLOOKUPREC pCacheRec pHCPtr = PATMR3GCPtrToHCPtr(pVM, pGCPtr); if (pHCPtr) - return pHCPtr; + return (uint8_t *)pHCPtr; if (pCacheRec->pPageLocStartHC) { @@ -716,10 +717,10 @@ static R3PTRTYPE(void *) CSAMGCVirtToHCVirt(PVM pVM, PCSAMP2GLOOKUPREC pCacheRec return NULL; } - pCacheRec->pPageLocStartHC = (R3PTRTYPE(uint8_t*))((RTHCUINTPTR)pHCPtr & PAGE_BASE_HC_MASK); + pCacheRec->pPageLocStartHC = (uint8_t*)((uintptr_t)pHCPtr & PAGE_BASE_HC_MASK); pCacheRec->pGuestLoc = pGCPtr & PAGE_BASE_GC_MASK; STAM_PROFILE_STOP(&pVM->csam.s.StatTimeAddrConv, a); - return pHCPtr; + return (uint8_t *)pHCPtr; } @@ -895,11 +896,10 @@ static int CSAMR3AnalyseCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_t * cbInstrs += cbCurInstr; { /* Force pCurInstrHC out of scope after we stop using it (page lock!) */ - uint8_t *pCurInstrHC = 0; - pCurInstrHC = (uint8_t *)CSAMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); + uint8_t *pCurInstrHC = csamR3GCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); if (pCurInstrHC == NULL) { - Log(("CSAMGCVirtToHCVirt failed for %RRv\n", pCurInstrGC)); + Log(("csamR3GCVirtToHCVirt failed for %RRv\n", pCurInstrGC)); break; } Assert(VALID_PTR(pCurInstrHC)); @@ -1077,10 +1077,10 @@ static int csamAnalyseCallCodeStream(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCP */ for (int j = 0; j < 16; j++) { - uint8_t *pCurInstrHC = (uint8_t *)CSAMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); + uint8_t *pCurInstrHC = csamR3GCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); if (pCurInstrHC == NULL) { - Log(("CSAMGCVirtToHCVirt failed for %RRv\n", pCurInstrGC)); + Log(("csamR3GCVirtToHCVirt failed for %RRv\n", pCurInstrGC)); goto done; } Assert(VALID_PTR(pCurInstrHC)); @@ -1289,10 +1289,10 @@ static int csamAnalyseCodeStream(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCPTRTY } { /* Force pCurInstrHC out of scope after we stop using it (page lock!) */ - uint8_t *pCurInstrHC = (uint8_t *)CSAMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); + uint8_t *pCurInstrHC = csamR3GCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); if (pCurInstrHC == NULL) { - Log(("CSAMGCVirtToHCVirt failed for %RRv\n", pCurInstrGC)); + Log(("csamR3GCVirtToHCVirt failed for %RRv\n", pCurInstrGC)); rc = VERR_PATCHING_REFUSED; goto done; } @@ -2324,7 +2324,7 @@ VMMR3DECL(int) CSAMR3CheckCode(PVM pVM, RTRCPTR pInstrGC) if (CSAMIsEnabled(pVM)) { - /* Cache record for CSAMGCVirtToHCVirt */ + /* Cache record for csamR3GCVirtToHCVirt */ CSAMP2GLOOKUPREC cacheRec; RT_ZERO(cacheRec); @@ -2490,7 +2490,7 @@ VMMR3DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates) if (pHandler) { PCSAMPAGE pPage = NULL; - CSAMP2GLOOKUPREC cacheRec; /* Cache record for CSAMGCVirtToHCVirt. */ + CSAMP2GLOOKUPREC cacheRec; /* Cache record for csamR3GCVirtToHCVirt. */ RT_ZERO(cacheRec); Log(("CSAMCheckGates: checking previous call instruction %RRv\n", pHandler)); @@ -2547,7 +2547,7 @@ VMMR3DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates) RTRCPTR pHandler; PCSAMPAGE pPage = NULL; DBGFSELINFO selInfo; - CSAMP2GLOOKUPREC cacheRec; /* Cache record for CSAMGCVirtToHCVirt. */ + CSAMP2GLOOKUPREC cacheRec; /* Cache record for csamR3GCVirtToHCVirt. */ RT_ZERO(cacheRec); pHandler = VBOXIDTE_OFFSET(*pGuestIdte); diff --git a/src/VBox/VMM/VMMR3/EM.cpp b/src/VBox/VMM/VMMR3/EM.cpp index 3eab7412fde..69fe733f0c7 100644 --- a/src/VBox/VMM/VMMR3/EM.cpp +++ b/src/VBox/VMM/VMMR3/EM.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2011 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; diff --git a/src/VBox/VMM/VMMR3/EMRaw.cpp b/src/VBox/VMM/VMMR3/EMRaw.cpp index 25205649d94..bc151a12866 100644 --- a/src/VBox/VMM/VMMR3/EMRaw.cpp +++ b/src/VBox/VMM/VMMR3/EMRaw.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 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; diff --git a/src/VBox/VMM/VMMR3/HM.cpp b/src/VBox/VMM/VMMR3/HM.cpp index d1aa823413b..e92f9383186 100644 --- a/src/VBox/VMM/VMMR3/HM.cpp +++ b/src/VBox/VMM/VMMR3/HM.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -699,7 +699,7 @@ VMMR3_INT_DECL(int) HMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat) static void hmR3DisableRawMode(PVM pVM) { /* Disable PATM & CSAM. */ - PATMR3AllowPatching(pVM, false); + PATMR3AllowPatching(pVM->pUVM, false); CSAMDisableScanning(pVM); /* Turn off IDT/LDT/GDT and TSS monitoring and sycing. */ diff --git a/src/VBox/VMM/VMMR3/PATM.cpp b/src/VBox/VMM/VMMR3/PATM.cpp index da110a7596f..9334cf75f0a 100644 --- a/src/VBox/VMM/VMMR3/PATM.cpp +++ b/src/VBox/VMM/VMMR3/PATM.cpp @@ -2,11 +2,11 @@ /** @file * PATM - Dynamic Guest OS Patching Manager * - * NOTE: Never ever reuse patch memory!! + * @note Never ever reuse patch memory!! */ /* - * Copyright (C) 2006-2012 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; @@ -34,11 +34,12 @@ #include <VBox/vmm/cfgm.h> #include <VBox/param.h> #include <VBox/vmm/selm.h> +#include <VBox/vmm/csam.h> #include <iprt/avl.h> #include "PATMInternal.h" #include "PATMPatch.h" #include <VBox/vmm/vm.h> -#include <VBox/vmm/csam.h> +#include <VBox/vmm/uvm.h> #include <VBox/dbg.h> #include <VBox/err.h> #include <VBox/log.h> @@ -107,6 +108,8 @@ static void patmPrintStat(PVM pVM, void *pvSample, char *pszBuf, size_t static int patmReinit(PVM pVM); static DECLCALLBACK(int) RelocatePatches(PAVLOU32NODECORE pNode, void *pParam); +static RTRCPTR patmR3GuestGCPtrToPatchGCPtrSimple(PVM pVM, RCPTRTYPE(uint8_t*) pInstrGC); +static int patmR3MarkDirtyPatch(PVM pVM, PPATCHINFO pPatch); #ifdef VBOX_WITH_DEBUGGER static DECLCALLBACK(int) DisableAllPatches(PAVLOU32NODECORE pNode, void *pVM); @@ -131,7 +134,7 @@ static unsigned int cIDTHandlersDisabled = 0; * @returns VBox status code. * @param pVM Pointer to the VM. */ -VMMR3DECL(int) PATMR3Init(PVM pVM) +VMMR3_INT_DECL(int) PATMR3Init(PVM pVM) { int rc; @@ -307,7 +310,7 @@ VMMR3DECL(int) PATMR3Init(PVM pVM) * @returns VBox status code. * @param pVM Pointer to the VM. */ -VMMR3DECL(int) PATMR3InitFinalize(PVM pVM) +VMMR3_INT_DECL(int) PATMR3InitFinalize(PVM pVM) { /* The GC state, stack and statistics must be read/write for the guest (supervisor only of course). */ int rc = PGMMapSetPage(pVM, pVM->patm.s.pGCStateGC, PAGE_SIZE, X86_PTE_P | X86_PTE_A | X86_PTE_D | X86_PTE_RW); @@ -437,7 +440,7 @@ static int patmReinit(PVM pVM) * * @param pVM The VM. */ -VMMR3DECL(void) PATMR3Relocate(PVM pVM) +VMMR3_INT_DECL(void) PATMR3Relocate(PVM pVM) { RTRCPTR GCPtrNew = MMHyperR3ToRC(pVM, pVM->patm.s.pGCStateHC); RTRCINTPTR delta = GCPtrNew - pVM->patm.s.pGCStateGC; @@ -492,7 +495,7 @@ VMMR3DECL(void) PATMR3Relocate(PVM pVM) * @returns VBox status code. * @param pVM Pointer to the VM. */ -VMMR3DECL(int) PATMR3Term(PVM pVM) +VMMR3_INT_DECL(int) PATMR3Term(PVM pVM) { /* Memory was all allocated from the two MM heaps and requires no freeing. */ NOREF(pVM); @@ -506,7 +509,7 @@ VMMR3DECL(int) PATMR3Term(PVM pVM) * @returns VBox status code. * @param pVM The VM which is reset. */ -VMMR3DECL(int) PATMR3Reset(PVM pVM) +VMMR3_INT_DECL(int) PATMR3Reset(PVM pVM) { Log(("PATMR3Reset\n")); @@ -515,9 +518,7 @@ VMMR3DECL(int) PATMR3Reset(PVM pVM) { PPATMPATCHREC pPatchRec = (PPATMPATCHREC)RTAvloU32RemoveBestFit(&pVM->patm.s.PatchLookupTreeHC->PatchTree, 0, true); if (pPatchRec) - { - PATMRemovePatch(pVM, pPatchRec, true); - } + patmR3RemovePatch(pVM, pPatchRec, true); else break; } @@ -920,8 +921,8 @@ DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void return VINF_PGM_HANDLER_DO_DEFAULT; } - #ifdef VBOX_WITH_DEBUGGER + /** * Callback function for RTAvloU32DoWithAll * @@ -938,10 +939,8 @@ static DECLCALLBACK(int) EnableAllPatches(PAVLOU32NODECORE pNode, void *pVM) PATMR3EnablePatch((PVM)pVM, (RTRCPTR)pPatch->Core.Key); return 0; } -#endif /* VBOX_WITH_DEBUGGER */ -#ifdef VBOX_WITH_DEBUGGER /** * Callback function for RTAvloU32DoWithAll * @@ -958,16 +957,19 @@ static DECLCALLBACK(int) DisableAllPatches(PAVLOU32NODECORE pNode, void *pVM) PATMR3DisablePatch((PVM)pVM, (RTRCPTR)pPatch->Core.Key); return 0; } -#endif + +#endif /* VBOX_WITH_DEBUGGER */ +#ifdef UNUSED_FUNCTIONS /** * Returns the host context pointer and size of the patch memory block * - * @returns VBox status code. + * @returns Host context pointer. * @param pVM Pointer to the VM. * @param pcb Size of the patch memory block + * @internal */ -VMMR3DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb) +VMMR3_INT_DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb) { if (pcb) *pcb = pVM->patm.s.cbPatchMem; @@ -979,11 +981,11 @@ VMMR3DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb) /** * Returns the guest context pointer and size of the patch memory block * - * @returns VBox status code. + * @returns Guest context pointer. * @param pVM Pointer to the VM. * @param pcb Size of the patch memory block */ -VMMR3DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb) +VMMR3_INT_DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb) { if (pcb) *pcb = pVM->patm.s.cbPatchMem; @@ -991,6 +993,7 @@ VMMR3DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb) return pVM->patm.s.pPatchMemGC; } +#endif /* UNUSED_FUNCTIONS */ /** * Returns the host context pointer of the GC context structure @@ -998,62 +1001,73 @@ VMMR3DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb) * @returns VBox status code. * @param pVM Pointer to the VM. */ -VMMR3DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM) +VMMR3_INT_DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM) { return pVM->patm.s.pGCStateHC; } +#ifdef UNUSED_FUNCTION /** * Checks whether the HC address is part of our patch region * - * @returns VBox status code. + * @returns true/false. * @param pVM Pointer to the VM. - * @param pAddrGC Guest context address + * @param pAddrHC Host context ring-3 address to check. */ -VMMR3DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, R3PTRTYPE(uint8_t *) pAddrHC) +VMMR3_INT_DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, void *pAddrHC) { - return (pAddrHC >= pVM->patm.s.pPatchMemHC && pAddrHC < pVM->patm.s.pPatchMemHC + pVM->patm.s.cbPatchMem) ? true : false; + return (uintptr_t)pAddrHC >= (uintptr_t)pVM->patm.s.pPatchMemHC + && (uintptr_t)pAddrHC < (uintptr_t)pVM->patm.s.pPatchMemHC + pVM->patm.s.cbPatchMem; } +#endif /** * Allows or disallow patching of privileged instructions executed by the guest OS * * @returns VBox status code. - * @param pVM Pointer to the VM. - * @param fAllowPatching Allow/disallow patching + * @param pUVM The user mode VM handle. + * @param fAllowPatching Allow/disallow patching */ -VMMR3DECL(int) PATMR3AllowPatching(PVM pVM, uint32_t fAllowPatching) +VMMR3DECL(int) PATMR3AllowPatching(PUVM pUVM, bool fAllowPatching) { - pVM->fPATMEnabled = (fAllowPatching) ? true : false; + UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); + PVM pVM = pUVM->pVM; + VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); + + pVM->fPATMEnabled = fAllowPatching; return VINF_SUCCESS; } + /** - * Convert a GC patch block pointer to a HC patch pointer + * Checks if the patch manager is enabled or not. * - * @returns HC pointer or NULL if it's not a GC patch pointer - * @param pVM Pointer to the VM. - * @param pAddrGC GC pointer + * @returns true if enabled, false if not (or if invalid handle). + * @param pUVM The user mode VM handle. */ -VMMR3DECL(R3PTRTYPE(void *)) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC) +VMMR3DECL(bool) PATMR3IsEnabled(PUVM pUVM) { - if (pVM->patm.s.pPatchMemGC <= pAddrGC && pVM->patm.s.pPatchMemGC + pVM->patm.s.cbPatchMem > pAddrGC) - return pVM->patm.s.pPatchMemHC + (pAddrGC - pVM->patm.s.pPatchMemGC); - else - return NULL; + UVM_ASSERT_VALID_EXT_RETURN(pUVM, false); + PVM pVM = pUVM->pVM; + VM_ASSERT_VALID_EXT_RETURN(pVM, false); + return PATMIsEnabled(pVM); } + /** - * Query PATM state (enabled/disabled) + * Convert a GC patch block pointer to a HC patch pointer * - * @returns 0 - disabled, 1 - enabled + * @returns HC pointer or NULL if it's not a GC patch pointer * @param pVM Pointer to the VM. + * @param pAddrGC GC pointer */ -VMMR3DECL(int) PATMR3IsEnabled(PVM pVM) +VMMR3_INT_DECL(void *) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC) { - return pVM->fPATMEnabled; + if (pVM->patm.s.pPatchMemGC <= pAddrGC && pVM->patm.s.pPatchMemGC + pVM->patm.s.cbPatchMem > pAddrGC) + return pVM->patm.s.pPatchMemHC + (pAddrGC - pVM->patm.s.pPatchMemGC); + return NULL; } @@ -1068,7 +1082,7 @@ VMMR3DECL(int) PATMR3IsEnabled(PVM pVM) * @returns Host context pointer or NULL in case of an error * */ -R3PTRTYPE(uint8_t *) PATMGCVirtToHCVirt(PVM pVM, PPATMP2GLOOKUPREC pCacheRec, RCPTRTYPE(uint8_t *) pGCPtr) +R3PTRTYPE(uint8_t *) patmR3GCVirtToHCVirt(PVM pVM, PPATMP2GLOOKUPREC pCacheRec, RCPTRTYPE(uint8_t *) pGCPtr) { int rc; R3PTRTYPE(uint8_t *) pHCPtr; @@ -1140,7 +1154,7 @@ static int patmr3SetBranchTargets(PVM pVM, PPATCHINFO pPatch) { /* Special case: call function replacement patch from this patch block. */ - PPATMPATCHREC pFunctionRec = PATMQueryFunctionPatch(pVM, pRec->pTargetGC); + PPATMPATCHREC pFunctionRec = patmQueryFunctionPatch(pVM, pRec->pTargetGC); if (!pFunctionRec) { int rc; @@ -1243,7 +1257,7 @@ static bool patmIsIllegalInstr(PPATCHINFO pPatch, RTRCPTR pInstrGC) * */ /** @note Be extremely careful with this function. Make absolutely sure the guest address is correct! (to avoid executing instructions twice!) */ -void patmr3AddP2GLookupRecord(PVM pVM, PPATCHINFO pPatch, uint8_t *pPatchInstrHC, RTRCPTR pInstrGC, PATM_LOOKUP_TYPE enmType, bool fDirty) +void patmR3AddP2GLookupRecord(PVM pVM, PPATCHINFO pPatch, uint8_t *pPatchInstrHC, RTRCPTR pInstrGC, PATM_LOOKUP_TYPE enmType, bool fDirty) { bool ret; PRECPATCHTOGUEST pPatchToGuestRec; @@ -1348,7 +1362,7 @@ static DECLCALLBACK(int) patmEmptyTreePVCallback(PAVLPVNODECORE pNode, void *) * @param pVM Pointer to the VM. * @param ppTree Tree to empty */ -void patmEmptyTree(PVM pVM, PAVLPVNODECORE *ppTree) +static void patmEmptyTree(PVM pVM, PAVLPVNODECORE *ppTree) { NOREF(pVM); RTAvlPVDestroy(ppTree, patmEmptyTreePVCallback, NULL); @@ -1370,7 +1384,7 @@ static DECLCALLBACK(int) patmEmptyTreeU32Callback(PAVLU32NODECORE pNode, void *) * @param pVM Pointer to the VM. * @param ppTree Tree to empty */ -void patmEmptyTreeU32(PVM pVM, PPAVLU32NODECORE ppTree) +static void patmEmptyTreeU32(PVM pVM, PPAVLU32NODECORE ppTree) { NOREF(pVM); RTAvlU32Destroy(ppTree, patmEmptyTreeU32Callback, NULL); @@ -1693,7 +1707,7 @@ static int patmRecompileCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_t * pPatch->flags &= ~PATMFL_RECOMPILE_NEXT; /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, PATCHCODE_PTR_HC(pPatch) + pPatch->uCurPatchOffset, pCurInstrGC, PATM_LOOKUP_BOTHDIR); + patmR3AddP2GLookupRecord(pVM, pPatch, PATCHCODE_PTR_HC(pPatch) + pPatch->uCurPatchOffset, pCurInstrGC, PATM_LOOKUP_BOTHDIR); /* Update lowest and highest instruction address for this patch */ if (pCurInstrGC < pPatch->pInstrGCLowest) @@ -1825,7 +1839,7 @@ static int patmRecompileCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_t * pNextInstrGC = pCurInstrGC + pCpu->cbInstr; { /* Force pNextInstrHC out of scope after using it */ - uint8_t *pNextInstrHC = PATMGCVirtToHCVirt(pVM, pCacheRec, pNextInstrGC); + uint8_t *pNextInstrHC = patmR3GCVirtToHCVirt(pVM, pCacheRec, pNextInstrGC); if (pNextInstrHC == NULL) { AssertFailed(); @@ -2149,7 +2163,7 @@ int patmr3DisasmCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_t *) pInstr pOrgJumpGC = patmPatchGCPtr2GuestGCPtr(pVM, pPatch, pCurInstrGC); { /* Force pOrgJumpHC out of scope after using it */ - uint8_t *pOrgJumpHC = PATMGCVirtToHCVirt(pVM, pCacheRec, pOrgJumpGC); + uint8_t *pOrgJumpHC = patmR3GCVirtToHCVirt(pVM, pCacheRec, pOrgJumpGC); bool disret = patmR3DisInstr(pVM, pPatch, pOrgJumpGC, pOrgJumpHC, PATMREAD_ORGCODE, &cpu, NULL); if (!disret || cpu.pCurInstr->uOpcode != OP_CALL || cpu.Param1.cb != 4 /* only near calls */) @@ -2210,7 +2224,7 @@ int patmr3DisasmCode(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCPTRTYPE(uint8_t * while (rc == VWRN_CONTINUE_ANALYSIS) { - pCurInstrHC = PATMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); + pCurInstrHC = patmR3GCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); if (pCurInstrHC == NULL) { rc = VERR_PATCHING_REFUSED; @@ -2342,9 +2356,9 @@ int patmr3DisasmCodeStream(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCPTRTYPE(uin * @note also checks for patch hints to make sure they can never be enabled if a conflict is present. * */ -VMMR3DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC) +VMMR3_INT_DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC) { - PPATCHINFO pTargetPatch = PATMFindActivePatchByEntrypoint(pVM, pConflictGC, true /* include patch hints */); + PPATCHINFO pTargetPatch = patmFindActivePatchByEntrypoint(pVM, pConflictGC, true /* include patch hints */); if (pTargetPatch) { return patmDisableUnusablePatch(pVM, pInstrGC, pConflictGC, pTargetPatch); @@ -2377,7 +2391,7 @@ static int patmRecompileCodeStream(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCPTR while (rc == VWRN_CONTINUE_RECOMPILE) { - pCurInstrHC = PATMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); + pCurInstrHC = patmR3GCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); if (pCurInstrHC == NULL) { rc = VERR_PATCHING_REFUSED; /* fatal in this case */ @@ -2395,7 +2409,7 @@ static int patmRecompileCodeStream(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCPTR Log(("Disassembly failed (probably page not present) -> return to caller\n")); /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, PATCHCODE_PTR_HC(pPatch) + pPatch->uCurPatchOffset, pCurInstrGC, PATM_LOOKUP_BOTHDIR); + patmR3AddP2GLookupRecord(pVM, pPatch, PATCHCODE_PTR_HC(pPatch) + pPatch->uCurPatchOffset, pCurInstrGC, PATM_LOOKUP_BOTHDIR); patmPatchGenIllegalInstr(pVM, pPatch); rc = VINF_SUCCESS; /* Note: don't fail here; we might refuse an important patch!! */ goto end; @@ -2418,7 +2432,7 @@ static int patmRecompileCodeStream(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCPTR /* Certain instructions (e.g. sti) force the next instruction to be executed before any interrupts can occur. * Recompile the next instruction as well */ - pNextInstrHC = PATMGCVirtToHCVirt(pVM, pCacheRec, pNextInstrGC); + pNextInstrHC = patmR3GCVirtToHCVirt(pVM, pCacheRec, pNextInstrGC); if (pNextInstrHC == NULL) { rc = VERR_PATCHING_REFUSED; /* fatal in this case */ @@ -2511,7 +2525,7 @@ static int patmRecompileCodeStream(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCPTR * * We rely on CSAM to detect and resolve conflicts */ - PPATCHINFO pTargetPatch = PATMFindActivePatchByEntrypoint(pVM, addr); + PPATCHINFO pTargetPatch = patmFindActivePatchByEntrypoint(pVM, addr); if(pTargetPatch) { Log(("Found active patch at target %RRv (%RRv) -> temporarily disabling it!!\n", addr, pTargetPatch->pPrivInstrGC)); @@ -2566,7 +2580,7 @@ static int patmGenJumpToPatch(PVM pVM, PPATCHINFO pPatch, PPATMP2GLOOKUPREC pCac Assert(pPatch->cbPatchJump <= sizeof(temp)); Assert(!(pPatch->flags & PATMFL_PATCHED_GUEST_CODE)); - pPB = PATMGCVirtToHCVirt(pVM, pCacheRec, pPatch->pPrivInstrGC); + pPB = patmR3GCVirtToHCVirt(pVM, pCacheRec, pPatch->pPrivInstrGC); Assert(pPB); #ifdef PATM_RESOLVE_CONFLICTS_WITH_JUMP_PATCHES @@ -2706,7 +2720,7 @@ static int patmGenCallToPatch(PVM pVM, PPATCHINFO pPatch, RTRCPTR pTargetGC, PPA Assert(pPatch->cbPatchJump <= sizeof(temp)); - pPB = PATMGCVirtToHCVirt(pVM, pCacheRec, pPatch->pPrivInstrGC); + pPB = patmR3GCVirtToHCVirt(pVM, pCacheRec, pPatch->pPrivInstrGC); Assert(pPB); Assert(pPatch->cbPatchJump == SIZEOF_NEARJUMP32); @@ -2746,8 +2760,8 @@ static int patmGenCallToPatch(PVM pVM, PPATCHINFO pPatch, RTRCPTR pTargetGC, PPA * @note returns failure if patching is not allowed or possible * */ -VMMR3DECL(int) PATMR3PatchBlock(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, - uint32_t uOpcode, uint32_t uOpSize, PPATMPATCHREC pPatchRec) +static int patmR3PatchBlock(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, + uint32_t uOpcode, uint32_t uOpSize, PPATMPATCHREC pPatchRec) { PPATCHINFO pPatch = &pPatchRec->patch; int rc = VERR_PATCHING_REFUSED; @@ -2776,7 +2790,7 @@ VMMR3DECL(int) PATMR3PatchBlock(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) default: if (!(pPatch->flags & PATMFL_IDTHANDLER)) { - AssertMsg(0, ("PATMR3PatchBlock: Invalid opcode %x\n", uOpcode)); + AssertMsg(0, ("patmR3PatchBlock: Invalid opcode %x\n", uOpcode)); return VERR_INVALID_PARAMETER; } } @@ -2849,7 +2863,7 @@ VMMR3DECL(int) PATMR3PatchBlock(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) { /* Most likely cause: we encountered an illegal instruction very early on. */ /** @todo could turn it into an int3 callable patch. */ - Log(("PATMR3PatchBlock: patch block too small -> refuse\n")); + Log(("patmR3PatchBlock: patch block too small -> refuse\n")); rc = VERR_PATCHING_REFUSED; goto failure; } @@ -2906,7 +2920,7 @@ VMMR3DECL(int) PATMR3PatchBlock(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) { /*uint8_t bASMInt3 = 0xCC; - unused */ - Log(("PATMR3PatchBlock %RRv -> int 3 callable patch.\n", pPatch->pPrivInstrGC)); + Log(("patmR3PatchBlock %RRv -> int 3 callable patch.\n", pPatch->pPrivInstrGC)); /* Replace first opcode byte with 'int 3'. */ rc = patmActivateInt3Patch(pVM, pPatch); if (RT_FAILURE(rc)) @@ -2987,7 +3001,7 @@ static int patmIdtHandler(PVM pVM, RTRCPTR pInstrGC, uint32_t uOpSize, PPATMPATC uint8_t *pCurInstrHC, *pInstrHC; uint32_t orgOffsetPatchMem = ~0; - pInstrHC = pCurInstrHC = PATMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); + pInstrHC = pCurInstrHC = patmR3GCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); AssertReturn(pCurInstrHC, VERR_PAGE_NOT_PRESENT); /* @@ -3042,7 +3056,7 @@ static int patmIdtHandler(PVM pVM, RTRCPTR pInstrGC, uint32_t uOpSize, PPATMPATC goto failure; /* Add lookup record for patch to guest address translation (for the push) */ - patmr3AddP2GLookupRecord(pVM, pPatch, PATCHCODE_PTR_HC(pPatch) + pPatch->uCurPatchOffset, pInstrGC, PATM_LOOKUP_BOTHDIR); + patmR3AddP2GLookupRecord(pVM, pPatch, PATCHCODE_PTR_HC(pPatch) + pPatch->uCurPatchOffset, pInstrGC, PATM_LOOKUP_BOTHDIR); /* Duplicate push. */ rc = patmPatchGenDuplicate(pVM, pPatch, &cpuPush, pInstrGC); @@ -3091,7 +3105,7 @@ failure: if (orgOffsetPatchMem != (uint32_t)~0) pVM->patm.s.offPatchMem = orgOffsetPatchMem; - return PATMR3PatchBlock(pVM, pInstrGC, pInstrHC, OP_CLI, uOpSize, pPatchRec); + return patmR3PatchBlock(pVM, pInstrGC, pInstrHC, OP_CLI, uOpSize, pPatchRec); } /** @@ -3495,7 +3509,7 @@ failure: * @param pCtx Pointer to the guest CPU context. * */ -VMMR3DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx) +VMMR3_INT_DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx) { RTRCPTR pBranchTarget, pPage; int rc; @@ -3560,7 +3574,7 @@ VMMR3DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx) STAM_COUNTER_INC(&pVM->patm.s.StatDuplicateREQFailed); } Assert(PATMIsPatchGCAddr(pVM, pCtx->edi)); - rc = PATMAddBranchToLookupCache(pVM, pCtx->edi, pBranchTarget, pCtx->eax); + rc = patmAddBranchToLookupCache(pVM, pCtx->edi, pBranchTarget, pCtx->eax); AssertRC(rc); pCtx->eip += PATM_ILLEGAL_INSTR_SIZE; @@ -3615,7 +3629,7 @@ static int patmReplaceFunctionCall(PVM pVM, DISCPUSTATE *pCpu, RTRCPTR pInstrGC, */ uint8_t *pTmpInstrHC; - pTmpInstrHC = PATMGCVirtToHCVirt(pVM, pCacheRec, pTargetGC); + pTmpInstrHC = patmR3GCVirtToHCVirt(pVM, pCacheRec, pTargetGC); Assert(pTmpInstrHC); if (pTmpInstrHC == 0) break; @@ -3695,7 +3709,7 @@ static int patmPatchMMIOInstr(PVM pVM, RTRCPTR pInstrGC, DISCPUSTATE *pCpu, PPAT if (pCpu->Param2.fUse != DISUSE_DISPLACEMENT32) goto failure; - pPB = PATMGCVirtToHCVirt(pVM, pCacheRec, pPatch->pPrivInstrGC); + pPB = patmR3GCVirtToHCVirt(pVM, pCacheRec, pPatch->pPrivInstrGC); if (pPB == 0) goto failure; @@ -3852,14 +3866,13 @@ static int patmDeactivateInt3Patch(PVM pVM, PPATCHINFO pPatch) * @note returns failure if patching is not allowed or possible * */ -VMMR3DECL(int) PATMR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu, - PPATCHINFO pPatch) +int patmR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu, PPATCHINFO pPatch) { uint8_t bASMInt3 = 0xCC; int rc; /* Note: Do not use patch memory here! It might called during patch installation too. */ - PATM_LOG_PATCH_INSTR(pVM, pPatch, PATMREAD_ORGCODE, "PATMR3PatchInstrInt3:", ""); + PATM_LOG_PATCH_INSTR(pVM, pPatch, PATMREAD_ORGCODE, "patmR3PatchInstrInt3:", ""); /* Save the original instruction. */ rc = PGMPhysSimpleReadGCPtr(VMMGetCpu0(pVM), pPatch->aPrivInstr, pPatch->pPrivInstrGC, pPatch->cbPrivInstr); @@ -3968,9 +3981,9 @@ int patmPatchJump(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISC * A conflict jump patch needs to be treated differently; we'll just replace the relative jump address with one that * references the target instruction in the conflict patch. */ - RTRCPTR pJmpDest = PATMR3GuestGCPtrToPatchGCPtr(pVM, pInstrGC + pCpu->cbInstr + (int32_t)pCpu->Param1.uValue); + RTRCPTR pJmpDest = patmR3GuestGCPtrToPatchGCPtrSimple(pVM, pInstrGC + pCpu->cbInstr + (int32_t)pCpu->Param1.uValue); - AssertMsg(pJmpDest, ("PATMR3GuestGCPtrToPatchGCPtr failed for %RRv\n", pInstrGC + pCpu->cbInstr + (int32_t)pCpu->Param1.uValue)); + AssertMsg(pJmpDest, ("patmR3GuestGCPtrToPatchGCPtrSimple failed for %RRv\n", pInstrGC + pCpu->cbInstr + (int32_t)pCpu->Param1.uValue)); pPatch->pPatchJumpDestGC = pJmpDest; PATMP2GLOOKUPREC cacheRec; @@ -4019,7 +4032,7 @@ failure: * @param pInstr Guest context point to privileged instruction * @param flags Patch flags */ -VMMR3DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags) +VMMR3_INT_DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags) { Assert(pInstrGC); Assert(flags == PATMFL_CODE32); @@ -4038,7 +4051,7 @@ VMMR3DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags) * * @note returns failure if patching is not allowed or possible */ -VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) +VMMR3_INT_DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) { DISCPUSTATE cpu; R3PTRTYPE(uint8_t *) pInstrHC; @@ -4064,7 +4077,7 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) /* Test for patch conflict only with patches that actually change guest code. */ if (!(flags & (PATMFL_GUEST_SPECIFIC|PATMFL_IDTHANDLER|PATMFL_INTHANDLER|PATMFL_TRAMPOLINE))) { - PPATCHINFO pConflictPatch = PATMFindActivePatchByEntrypoint(pVM, pInstrGC); + PPATCHINFO pConflictPatch = patmFindActivePatchByEntrypoint(pVM, pInstrGC); AssertReleaseMsg(pConflictPatch == 0, ("Unable to patch overwritten instruction at %RRv (%RRv)\n", pInstrGC, pConflictPatch->pPrivInstrGC)); if (pConflictPatch != 0) return VERR_PATCHING_REFUSED; @@ -4231,7 +4244,7 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) PATMP2GLOOKUPREC cacheRec; RT_ZERO(cacheRec); - pInstrHC = PATMGCVirtToHCVirt(pVM, &cacheRec, pInstrGC); + pInstrHC = patmR3GCVirtToHCVirt(pVM, &cacheRec, pInstrGC); AssertReturn(pInstrHC, VERR_PATCHING_REFUSED); /* Allocate patch record. */ @@ -4336,7 +4349,7 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) else if (pPatchRec->patch.flags & PATMFL_INT3_REPLACEMENT) { - rc = PATMR3PatchInstrInt3(pVM, pInstrGC, pInstrHC, &cpu, &pPatchRec->patch); + rc = patmR3PatchInstrInt3(pVM, pInstrGC, pInstrHC, &cpu, &pPatchRec->patch); } else if (pPatchRec->patch.flags & PATMFL_MMIO_ACCESS) @@ -4365,7 +4378,7 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) { case OP_SYSENTER: case OP_PUSH: - rc = PATMInstallGuestSpecificPatch(pVM, &cpu, pInstrGC, pInstrHC, pPatchRec); + rc = patmR3InstallGuestSpecificPatch(pVM, &cpu, pInstrGC, pInstrHC, pPatchRec); if (rc == VINF_SUCCESS) { if (rc == VINF_SUCCESS) @@ -4384,7 +4397,7 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) switch (cpu.pCurInstr->uOpcode) { case OP_SYSENTER: - rc = PATMInstallGuestSpecificPatch(pVM, &cpu, pInstrGC, pInstrHC, pPatchRec); + rc = patmR3InstallGuestSpecificPatch(pVM, &cpu, pInstrGC, pInstrHC, pPatchRec); if (rc == VINF_SUCCESS) { Log(("PATMR3InstallPatch GUEST: %s %RRv code32=%d\n", patmGetInstructionString(pPatchRec->patch.opcode, pPatchRec->patch.flags), pInstrGC, (flags & PATMFL_CODE32) ? 1 : 0)); @@ -4425,7 +4438,7 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) case OP_PUSHF: case OP_CLI: Log(("PATMR3InstallPatch %s %RRv code32=%d\n", patmGetInstructionString(pPatchRec->patch.opcode, pPatchRec->patch.flags), pInstrGC, (flags & PATMFL_CODE32) ? 1 : 0)); - rc = PATMR3PatchBlock(pVM, pInstrGC, pInstrHC, cpu.pCurInstr->uOpcode, cbInstr, pPatchRec); + rc = patmR3PatchBlock(pVM, pInstrGC, pInstrHC, cpu.pCurInstr->uOpcode, cbInstr, pPatchRec); break; case OP_STR: @@ -4439,7 +4452,7 @@ VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags) case OP_VERW: case OP_VERR: case OP_IRET: - rc = PATMR3PatchInstrInt3(pVM, pInstrGC, pInstrHC, &cpu, &pPatchRec->patch); + rc = patmR3PatchInstrInt3(pVM, pInstrGC, pInstrHC, &cpu, &pPatchRec->patch); break; default: @@ -4772,7 +4785,7 @@ int patmInsertPatchPages(PVM pVM, PPATCHINFO pPatch) * @param pVM Pointer to the VM. * @param pPatch Patch record */ -int patmRemovePatchPages(PVM pVM, PPATCHINFO pPatch) +static int patmRemovePatchPages(PVM pVM, PPATCHINFO pPatch) { int rc; RTRCUINTPTR pPatchPageStart, pPatchPageEnd, pPage; @@ -4807,7 +4820,7 @@ int patmRemovePatchPages(PVM pVM, PPATCHINFO pPatch) * @param cbWrite Nr of bytes to write * */ -VMMR3DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite) +VMMR3_INT_DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite) { RTRCUINTPTR pWritePageStart, pWritePageEnd, pPage; @@ -4904,7 +4917,7 @@ loop_start: { LogRel(("PATM: Disable block at %RRv - write %RRv-%RRv\n", pPatch->pPrivInstrGC, pGuestPtrGC, pGuestPtrGC+cbWrite)); - PATMR3MarkDirtyPatch(pVM, pPatch); + patmR3MarkDirtyPatch(pVM, pPatch); /* Note: jump back to the start as the pPatchPage has been deleted or changed */ goto loop_start; @@ -4957,7 +4970,7 @@ invalid_write_loop_start: else { LogRel(("PATM: Disable block at %RRv - invalid write %RRv-%RRv \n", pPatch->pPrivInstrGC, GCPtr, GCPtr+cbWrite)); - PATMR3MarkDirtyPatch(pVM, pPatch); + patmR3MarkDirtyPatch(pVM, pPatch); } /* Note: jump back to the start as the pPatchPage has been deleted or changed */ goto invalid_write_loop_start; @@ -4981,7 +4994,7 @@ invalid_write_loop_start: */ /** @note Currently only called by CSAMR3FlushPage; optimization to avoid having to double check if the physical address has changed */ -VMMR3DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr) +VMMR3_INT_DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr) { addr &= PAGE_BASE_GC_MASK; @@ -4998,7 +5011,7 @@ VMMR3DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr) PPATCHINFO pPatch = pPatchPage->papPatch[i]; Log(("PATMR3FlushPage %RRv remove patch at %RRv\n", addr, pPatch->pPrivInstrGC)); - PATMR3MarkDirtyPatch(pVM, pPatch); + patmR3MarkDirtyPatch(pVM, pPatch); } } STAM_COUNTER_INC(&pVM->patm.s.StatFlushed); @@ -5013,7 +5026,7 @@ VMMR3DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr) * @param pVM Pointer to the VM. * @param pInstrGC Guest context pointer to instruction */ -VMMR3DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC) +VMMR3_INT_DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC) { PPATMPATCHREC pPatchRec; pPatchRec = (PPATMPATCHREC)RTAvloU32Get(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pInstrGC); @@ -5076,7 +5089,7 @@ VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte) * @param cbToRead The maximum number bytes to read. * @param pcbRead Where to return the acutal number of bytes read. */ -VMMR3DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead) +VMMR3_INT_DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead) { /* Shortcut. */ if ( !PATMIsEnabled(pVM) @@ -5133,7 +5146,7 @@ VMMR3DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, * @note returns failure if patching is not allowed or possible * */ -VMMR3DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC) +VMMR3_INT_DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC) { PPATMPATCHREC pPatchRec; PPATCHINFO pPatch; @@ -5292,7 +5305,7 @@ static int patmDisableUnusablePatch(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflict int rc; RT_ZERO(patch); - pInstrHC = PATMGCVirtToHCVirt(pVM, &patch, pInstrGC); + pInstrHC = patmR3GCVirtToHCVirt(pVM, &patch, pInstrGC); disret = patmR3DisInstr(pVM, &patch, pInstrGC, pInstrHC, PATMREAD_ORGCODE, &cpu, &cbInstr); /* * If it's a 5 byte relative jump, then we can work around the problem by replacing the 32 bits relative offset @@ -5379,7 +5392,7 @@ static int patmDisableUnusablePatch(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflict * @note returns failure if patching is not allowed or possible * */ -VMMR3DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC) +VMMR3_INT_DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC) { PPATMPATCHREC pPatchRec; PPATCHINFO pPatch; @@ -5498,7 +5511,7 @@ VMMR3DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC) * @param pPatchRec Patch record * @param fForceRemove Remove *all* patches */ -int PATMRemovePatch(PVM pVM, PPATMPATCHREC pPatchRec, bool fForceRemove) +int patmR3RemovePatch(PVM pVM, PPATMPATCHREC pPatchRec, bool fForceRemove) { PPATCHINFO pPatch; @@ -5710,7 +5723,7 @@ int patmR3RefreshPatch(PVM pVM, PPATMPATCHREC pPatchRec) Assert(pNewPatchRec); /* can't fail */ /* Remove old patch (only do that when everything is finished) */ - int rc2 = PATMRemovePatch(pVM, pPatchRec, true /* force removal */); + int rc2 = patmR3RemovePatch(pVM, pPatchRec, true /* force removal */); AssertRC(rc2); /* Put the new patch back into the tree, because removing the old one kicked this one out. (hack alert) */ @@ -5787,7 +5800,7 @@ failure: * @param fIncludeHints Include hinted patches or not * */ -PPATCHINFO PATMFindActivePatchByEntrypoint(PVM pVM, RTRCPTR pInstrGC, bool fIncludeHints) +PPATCHINFO patmFindActivePatchByEntrypoint(PVM pVM, RTRCPTR pInstrGC, bool fIncludeHints) { PPATMPATCHREC pPatchRec = (PPATMPATCHREC)RTAvloU32GetBestFit(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pInstrGC, false); /* if the patch is enabled, the pointer is not identical to the privileged patch ptr and it lies within 5 bytes of this priv instr ptr, then we've got a hit! */ @@ -5820,10 +5833,10 @@ PPATCHINFO PATMFindActivePatchByEntrypoint(PVM pVM, RTRCPTR pInstrGC, bool fIncl * * @returns true -> yes, false -> no * @param pVM Pointer to the VM. - * @param pAddr Guest context address - * @param pPatchAddr Guest context patch address (if true) + * @param pAddr Guest context address. + * @param pPatchAddr Guest context patch address (if true). */ -VMMR3DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr) +VMMR3_INT_DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr) { RTRCPTR addr; PPATCHINFO pPatch; @@ -5836,7 +5849,7 @@ VMMR3DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatc *pPatchAddr = 0; - pPatch = PATMFindActivePatchByEntrypoint(pVM, pAddr); + pPatch = patmFindActivePatchByEntrypoint(pVM, pAddr); if (pPatch) *pPatchAddr = pPatch->pPrivInstrGC; @@ -5853,7 +5866,7 @@ VMMR3DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatc * @note returns failure if patching is not allowed or possible * */ -VMMR3DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC) +VMMR3_INT_DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC) { PPATMPATCHREC pPatchRec; @@ -5864,7 +5877,7 @@ VMMR3DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC) if (rc == VWRN_PATCH_REMOVED) return VINF_SUCCESS; - return PATMRemovePatch(pVM, pPatchRec, false); + return patmR3RemovePatch(pVM, pPatchRec, false); } AssertFailed(); return VERR_PATCH_NOT_FOUND; @@ -5880,7 +5893,7 @@ VMMR3DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC) * @note returns failure if patching is not allowed or possible * */ -VMMR3DECL(int) PATMR3MarkDirtyPatch(PVM pVM, PPATCHINFO pPatch) +static int patmR3MarkDirtyPatch(PVM pVM, PPATCHINFO pPatch) { if (pPatch->pPatchBlockOffset) { @@ -5951,37 +5964,37 @@ RTRCPTR patmGuestGCPtrToPatchGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t return 0; } -/* Converts Guest code GC ptr to Patch code GC ptr (or nearest from below if no identical match) +/** + * Converts Guest code GC ptr to Patch code GC ptr (if found) * * @returns corresponding GC pointer in patch block * @param pVM Pointer to the VM. - * @param pPatch Current patch block pointer * @param pInstrGC Guest context pointer to privileged instruction - * */ -RTRCPTR patmGuestGCPtrToClosestPatchGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t*) pInstrGC) +static RTRCPTR patmR3GuestGCPtrToPatchGCPtrSimple(PVM pVM, RCPTRTYPE(uint8_t*) pInstrGC) { - PRECGUESTTOPATCH pGuestToPatchRec = (PRECGUESTTOPATCH)RTAvlU32GetBestFit(&pPatch->Guest2PatchAddrTree, pInstrGC, false); - if (pGuestToPatchRec) - return pVM->patm.s.pPatchMemGC + pGuestToPatchRec->PatchOffset; - - return 0; + PPATMPATCHREC pPatchRec = (PPATMPATCHREC)RTAvloU32GetBestFit(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pInstrGC, false); + if (pPatchRec && pPatchRec->patch.uState == PATCH_ENABLED && pInstrGC >= pPatchRec->patch.pPrivInstrGC) + return patmGuestGCPtrToPatchGCPtr(pVM, &pPatchRec->patch, pInstrGC); + return NIL_RTRCPTR; } -/* Converts Guest code GC ptr to Patch code GC ptr (if found) +/** + * Converts Guest code GC ptr to Patch code GC ptr (or nearest from below if no + * identical match) * * @returns corresponding GC pointer in patch block * @param pVM Pointer to the VM. + * @param pPatch Current patch block pointer * @param pInstrGC Guest context pointer to privileged instruction * */ -VMMR3DECL(RTRCPTR) PATMR3GuestGCPtrToPatchGCPtr(PVM pVM, RCPTRTYPE(uint8_t*) pInstrGC) +RTRCPTR patmGuestGCPtrToClosestPatchGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t*) pInstrGC) { - PPATMPATCHREC pPatchRec = (PPATMPATCHREC)RTAvloU32GetBestFit(&pVM->patm.s.PatchLookupTreeHC->PatchTree, pInstrGC, false); - if (pPatchRec && pPatchRec->patch.uState == PATCH_ENABLED && pInstrGC >= pPatchRec->patch.pPrivInstrGC) - return patmGuestGCPtrToPatchGCPtr(pVM, &pPatchRec->patch, pInstrGC); - else - return 0; + PRECGUESTTOPATCH pGuestToPatchRec = (PRECGUESTTOPATCH)RTAvlU32GetBestFit(&pPatch->Guest2PatchAddrTree, pInstrGC, false); + if (pGuestToPatchRec) + return pVM->patm.s.pPatchMemGC + pGuestToPatchRec->PatchOffset; + return NIL_RTRCPTR; } /** @@ -5993,7 +6006,7 @@ VMMR3DECL(RTRCPTR) PATMR3GuestGCPtrToPatchGCPtr(PVM pVM, RCPTRTYPE(uint8_t*) pIn * @param pEnmState State of the translated address (out) * */ -VMMR3DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState) +VMMR3_INT_DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState) { PPATMPATCHREC pPatchRec; void *pvPatchCoreOffset; @@ -6037,7 +6050,7 @@ VMMR3DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState = PATMTRANS_OVERWRITTEN; } else - if (PATMFindActivePatchByEntrypoint(pVM, pPrivInstrGC)) + if (patmFindActivePatchByEntrypoint(pVM, pPrivInstrGC)) { *pEnmState = PATMTRANS_OVERWRITTEN; } @@ -6059,7 +6072,7 @@ VMMR3DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE * @param pVM Pointer to the VM. * @param pAddrGC Guest context address */ -VMMR3DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC) +VMMR3_INT_DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC) { PPATMPATCHREC pPatchRec; @@ -6068,8 +6081,7 @@ VMMR3DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC) /** @todo we should only use patches that are enabled! always did this, but it's incorrect! */ if (pPatchRec && (pPatchRec->patch.uState == PATCH_ENABLED || pPatchRec->patch.uState == PATCH_DIRTY)) return PATCHCODE_PTR_GC(&pPatchRec->patch); - else - return 0; + return NIL_RTRCPTR; } /** @@ -6202,7 +6214,7 @@ static int patmR3HandleDirtyInstr(PVM pVM, PCPUMCTX pCtx, PPATMPATCHREC pPatch, AssertRC(rc); /* Add a new lookup record for the duplicated instruction. */ - patmr3AddP2GLookupRecord(pVM, &pPatch->patch, pCurPatchInstrHC, pCurInstrGC, PATM_LOOKUP_BOTHDIR); + patmR3AddP2GLookupRecord(pVM, &pPatch->patch, pCurPatchInstrHC, pCurInstrGC, PATM_LOOKUP_BOTHDIR); } else { @@ -6213,7 +6225,7 @@ static int patmR3HandleDirtyInstr(PVM pVM, PCPUMCTX pCtx, PPATMPATCHREC pPatch, Log(("NEW: %s (FAILED)\n", szBuf)); #endif /* Restore the old lookup record for the duplicated instruction. */ - patmr3AddP2GLookupRecord(pVM, &pPatch->patch, pCurPatchInstrHC, pCurInstrGC, PATM_LOOKUP_BOTHDIR); + patmR3AddP2GLookupRecord(pVM, &pPatch->patch, pCurPatchInstrHC, pCurInstrGC, PATM_LOOKUP_BOTHDIR); /** @todo in theory we need to restore the lookup records for the remaining dirty instructions too! */ rc = VERR_PATCHING_REFUSED; @@ -6308,7 +6320,7 @@ static int patmR3HandleDirtyInstr(PVM pVM, PCPUMCTX pCtx, PPATMPATCHREC pPatch, * @param pEip GC pointer of trapping instruction. * @param ppNewEip GC pointer to new instruction. */ -VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip) +VMMR3_INT_DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip) { PPATMPATCHREC pPatch = 0; void *pvPatchCoreOffset; @@ -6507,7 +6519,7 @@ VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *p RT_ZERO(cacheRec); cacheRec.pPatch = &pPatch->patch; - disret = patmR3DisInstr(pVM, &pPatch->patch, pNewEip, PATMGCVirtToHCVirt(pVM, &cacheRec, pNewEip), PATMREAD_RAWCODE, + disret = patmR3DisInstr(pVM, &pPatch->patch, pNewEip, patmR3GCVirtToHCVirt(pVM, &cacheRec, pNewEip), PATMREAD_RAWCODE, &cpu, &cbInstr); if (cacheRec.Lock.pvMap) PGMPhysReleasePageMappingLock(pVM, &cacheRec.Lock); @@ -6546,14 +6558,14 @@ VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *p RT_ZERO(cacheRec); cacheRec.pPatch = &pPatch->patch; - disret = patmR3DisInstr(pVM, &pPatch->patch, pNewEip, PATMGCVirtToHCVirt(pVM, &cacheRec, pNewEip), PATMREAD_ORGCODE, + disret = patmR3DisInstr(pVM, &pPatch->patch, pNewEip, patmR3GCVirtToHCVirt(pVM, &cacheRec, pNewEip), PATMREAD_ORGCODE, &cpu, &cbInstr); if (cacheRec.Lock.pvMap) PGMPhysReleasePageMappingLock(pVM, &cacheRec.Lock); if (disret && (cpu.pCurInstr->uOpcode == OP_SYSEXIT || cpu.pCurInstr->uOpcode == OP_HLT || cpu.pCurInstr->uOpcode == OP_INT3)) { - disret = patmR3DisInstr(pVM, &pPatch->patch, pNewEip, PATMGCVirtToHCVirt(pVM, &cacheRec, pNewEip), PATMREAD_RAWCODE, + disret = patmR3DisInstr(pVM, &pPatch->patch, pNewEip, patmR3GCVirtToHCVirt(pVM, &cacheRec, pNewEip), PATMREAD_RAWCODE, &cpu, &cbInstr); if (cacheRec.Lock.pvMap) PGMPhysReleasePageMappingLock(pVM, &cacheRec.Lock); @@ -6600,7 +6612,7 @@ VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *p * @returns VBox status code. * @param pVM Pointer to the VM. */ -VMMR3DECL(int) PATMR3HandleMonitoredPage(PVM pVM) +VMMR3_INT_DECL(int) PATMR3HandleMonitoredPage(PVM pVM) { RTRCPTR addr = pVM->patm.s.pvFaultMonitor; @@ -6774,7 +6786,7 @@ static DECLCALLBACK(int) patmr3CmdOff(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM p return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires VM to be selected.\n"); RTAvloU32DoWithAll(&pVM->patm.s.PatchLookupTreeHC->PatchTree, true, DisableAllPatches, pVM); - PATMR3AllowPatching(pVM, false); + PATMR3AllowPatching(pVM->pUVM, false); return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Patching disabled\n"); } @@ -6797,7 +6809,7 @@ static DECLCALLBACK(int) patmr3CmdOn(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pV if (!pVM) return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires VM to be selected.\n"); - PATMR3AllowPatching(pVM, true); + PATMR3AllowPatching(pVM->pUVM, true); RTAvloU32DoWithAll(&pVM->patm.s.PatchLookupTreeHC->PatchTree, true, EnableAllPatches, pVM); return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Patching enabled\n"); } diff --git a/src/VBox/VMM/VMMR3/PATMGuest.cpp b/src/VBox/VMM/VMMR3/PATMGuest.cpp index 8932432ca4e..64011f8e044 100644 --- a/src/VBox/VMM/VMMR3/PATMGuest.cpp +++ b/src/VBox/VMM/VMMR3/PATMGuest.cpp @@ -194,7 +194,7 @@ int PATMPatchOpenBSDHandlerPrefix(PVM pVM, PDISCPUSTATE pCpu, RTGCPTR32 pInstrGC } /* Found it; patch the push cs */ pPatchRec->patch.flags &= ~(PATMFL_GUEST_SPECIFIC); /* prevent a breakpoint from being triggered */ - return PATMR3PatchInstrInt3(pVM, pInstrGC, pInstrHC, pCpu, &pPatchRec->patch); + return patmR3PatchInstrInt3(pVM, pInstrGC, pInstrHC, pCpu, &pPatchRec->patch); } /** @@ -209,7 +209,7 @@ int PATMPatchOpenBSDHandlerPrefix(PVM pVM, PDISCPUSTATE pCpu, RTGCPTR32 pInstrGC * @param pPatchRec Patch structure * */ -int PATMInstallGuestSpecificPatch(PVM pVM, PDISCPUSTATE pCpu, RTGCPTR32 pInstrGC, uint8_t *pInstrHC, PPATMPATCHREC pPatchRec) +int patmR3InstallGuestSpecificPatch(PVM pVM, PDISCPUSTATE pCpu, RTGCPTR32 pInstrGC, uint8_t *pInstrHC, PPATMPATCHREC pPatchRec) { int rc; diff --git a/src/VBox/VMM/VMMR3/PATMPatch.cpp b/src/VBox/VMM/VMMR3/PATMPatch.cpp index d3de8a561ba..08c060a3f9a 100644 --- a/src/VBox/VMM/VMMR3/PATMPatch.cpp +++ b/src/VBox/VMM/VMMR3/PATMPatch.cpp @@ -373,7 +373,7 @@ static uint32_t patmPatchGenCode(PVM pVM, PPATCHINFO pPatch, uint8_t *pPB, PPATC /* Add lookup record for patch to guest address translation */ Assert(pPB[pAsmRecord->offJump - 1] == 0xE9); - patmr3AddP2GLookupRecord(pVM, pPatch, &pPB[pAsmRecord->offJump - 1], pReturnAddrGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, &pPB[pAsmRecord->offJump - 1], pReturnAddrGC, PATM_LOOKUP_PATCH2GUEST); *(uint32_t *)&pPB[pAsmRecord->offJump] = displ; patmPatchAddReloc32(pVM, pPatch, &pPB[pAsmRecord->offJump], FIXUP_REL_JMPTOGUEST, @@ -636,7 +636,7 @@ int patmPatchGenRelJump(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t *) pTarget case OP_JMP: /* If interrupted here, then jump to the target instruction. Used by PATM.cpp for jumping to known instructions. */ /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pTargetGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pTargetGC, PATM_LOOKUP_PATCH2GUEST); pPB[0] = 0xE9; break; @@ -865,7 +865,7 @@ int patmPatchGenRet(PVM pVM, PPATCHINFO pPatch, DISCPUSTATE *pCpu, RCPTRTYPE(uin } /* Jump back to the original instruction if IF is set again. */ - Assert(!PATMFindActivePatchByEntrypoint(pVM, pCurInstrGC)); + Assert(!patmFindActivePatchByEntrypoint(pVM, pCurInstrGC)); rc = patmPatchGenCheckIF(pVM, pPatch, pCurInstrGC); AssertRCReturn(rc, rc); @@ -978,7 +978,7 @@ int patmPatchGenCheckIF(PVM pVM, PPATCHINFO pPatch, RTRCPTR pCurInstrGC) PATCHGEN_PROLOG(pVM, pPatch); /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pCurInstrGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pCurInstrGC, PATM_LOOKUP_PATCH2GUEST); /* Generate code to check for IF=1 before executing the call to the duplicated function. */ size = patmPatchGenCode(pVM, pPatch, pPB, &PATMCheckIFRecord, pCurInstrGC, true); @@ -1001,7 +1001,7 @@ int patmPatchGenSetPIF(PVM pVM, PPATCHINFO pPatch, RTRCPTR pInstrGC) PATCHGEN_PROLOG(pVM, pPatch); /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pInstrGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pInstrGC, PATM_LOOKUP_PATCH2GUEST); int size = patmPatchGenCode(pVM, pPatch, pPB, &PATMSetPIFRecord, 0, false); PATCHGEN_EPILOG(pPatch, size); @@ -1022,7 +1022,7 @@ int patmPatchGenClearPIF(PVM pVM, PPATCHINFO pPatch, RTRCPTR pInstrGC) PATCHGEN_PROLOG(pVM, pPatch); /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pInstrGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pInstrGC, PATM_LOOKUP_PATCH2GUEST); int size = patmPatchGenCode(pVM, pPatch, pPB, &PATMClearPIFRecord, 0, false); PATCHGEN_EPILOG(pPatch, size); @@ -1048,7 +1048,7 @@ int patmPatchGenClearInhibitIRQ(PVM pVM, PPATCHINFO pPatch, RTRCPTR pNextInstrGC Assert((pPatch->flags & (PATMFL_GENERATE_JUMPTOGUEST|PATMFL_DUPLICATE_FUNCTION)) != (PATMFL_GENERATE_JUMPTOGUEST|PATMFL_DUPLICATE_FUNCTION)); /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pNextInstrGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pNextInstrGC, PATM_LOOKUP_PATCH2GUEST); callInfo.pNextInstrGC = pNextInstrGC; @@ -1079,7 +1079,7 @@ int patmPatchGenIntEntry(PVM pVM, PPATCHINFO pPatch, RTRCPTR pIntHandlerGC) PATCHGEN_PROLOG(pVM, pPatch); /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pIntHandlerGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pIntHandlerGC, PATM_LOOKUP_PATCH2GUEST); /* Generate entrypoint for the interrupt handler (correcting CS in the interrupt stack frame) */ size = patmPatchGenCode(pVM, pPatch, pPB, @@ -1110,7 +1110,7 @@ int patmPatchGenTrapEntry(PVM pVM, PPATCHINFO pPatch, RTRCPTR pTrapHandlerGC) PATCHGEN_PROLOG(pVM, pPatch); /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pTrapHandlerGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pTrapHandlerGC, PATM_LOOKUP_PATCH2GUEST); /* Generate entrypoint for the trap handler (correcting CS in the interrupt stack frame) */ size = patmPatchGenCode(pVM, pPatch, pPB, @@ -1129,7 +1129,7 @@ int patmPatchGenStats(PVM pVM, PPATCHINFO pPatch, RTRCPTR pInstrGC) PATCHGEN_PROLOG(pVM, pPatch); /* Add lookup record for stats code -> guest handler. */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pInstrGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pInstrGC, PATM_LOOKUP_PATCH2GUEST); /* Generate code to keep calling statistics for this patch */ size = patmPatchGenCode(pVM, pPatch, pPB, &PATMStatsRecord, pInstrGC, false); @@ -1544,7 +1544,7 @@ int patmPatchGenJumpToGuest(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t *) pRe PATCHGEN_PROLOG(pVM, pPatch); /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pReturnAddrGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pReturnAddrGC, PATM_LOOKUP_PATCH2GUEST); /* Generate code to jump to guest code if IF=1, else fault. */ size = patmPatchGenCode(pVM, pPatch, pPB, &PATMJumpToGuest_IF1Record, pReturnAddrGC, true); @@ -1567,7 +1567,7 @@ int patmPatchGenPatchJump(PVM pVM, PPATCHINFO pPatch, RTRCPTR pCurInstrGC, RCPTR if (fAddLookupRecord) { /* Add lookup record for patch to guest address translation */ - patmr3AddP2GLookupRecord(pVM, pPatch, pPB, pCurInstrGC, PATM_LOOKUP_PATCH2GUEST); + patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pCurInstrGC, PATM_LOOKUP_PATCH2GUEST); } pPB[0] = 0xE9; //JMP diff --git a/src/VBox/VMM/VMMR3/PATMSSM.cpp b/src/VBox/VMM/VMMR3/PATMSSM.cpp index 3d4c12b9f88..dc31e37d452 100644 --- a/src/VBox/VMM/VMMR3/PATMSSM.cpp +++ b/src/VBox/VMM/VMMR3/PATMSSM.cpp @@ -828,7 +828,7 @@ DECLCALLBACK(int) patmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32 RT_ZERO(cacheRec); cacheRec.pPatch = &pPatchRec->patch; - uint8_t *pPrivInstrHC = PATMGCVirtToHCVirt(pVM, &cacheRec, pPatchRec->patch.pPrivInstrGC); + uint8_t *pPrivInstrHC = patmR3GCVirtToHCVirt(pVM, &cacheRec, pPatchRec->patch.pPrivInstrGC); /* Can fail due to page or page table not present. */ /* @@ -894,7 +894,7 @@ DECLCALLBACK(int) patmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32 rc = SSMR3GetStructEx(pSSM, &rec, sizeof(rec), SSMSTRUCT_FLAGS_MEM_BAND_AID, &g_aPatmRecPatchToGuest[0], NULL); AssertRCReturn(rc, rc); - patmr3AddP2GLookupRecord(pVM, &pPatchRec->patch, (uintptr_t)rec.Core.Key + pVM->patm.s.pPatchMemHC, rec.pOrgInstrGC, rec.enmType, rec.fDirty); + patmR3AddP2GLookupRecord(pVM, &pPatchRec->patch, (uintptr_t)rec.Core.Key + pVM->patm.s.pPatchMemHC, rec.pOrgInstrGC, rec.enmType, rec.fDirty); } Assert(pPatchRec->patch.Patch2GuestAddrTree); } diff --git a/src/VBox/VMM/VMMRC/CSAMRC.cpp b/src/VBox/VMM/VMMRC/CSAMRC.cpp index fbd8978ca40..ebfa99b0b09 100644 --- a/src/VBox/VMM/VMMRC/CSAMRC.cpp +++ b/src/VBox/VMM/VMMRC/CSAMRC.cpp @@ -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; @@ -108,7 +108,7 @@ VMMRCDECL(int) CSAMGCCodePageWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTX /* If user code is modifying one of our monitored pages, then we can safely make it r/w as it's no longer being used for supervisor code. */ if (cpl != 3) { - rc = PATMGCHandleWriteToPatchPage(pVM, pRegFrame, (RTRCPTR)((RTRCUINTPTR)pvRange + offRange), 4 /** @todo */); + rc = PATMRCHandleWriteToPatchPage(pVM, pRegFrame, (RTRCPTR)((RTRCUINTPTR)pvRange + offRange), 4 /** @todo */); if (rc == VINF_SUCCESS) return rc; if (rc == VINF_EM_RAW_EMULATE_INSTR) diff --git a/src/VBox/VMM/VMMRC/PATMRC.cpp b/src/VBox/VMM/VMMRC/PATMRC.cpp index c1505648a5d..0b1a040c7da 100644 --- a/src/VBox/VMM/VMMRC/PATMRC.cpp +++ b/src/VBox/VMM/VMMRC/PATMRC.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -75,7 +75,7 @@ VMMRCDECL(int) PATMGCMonitorPage(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pReg * @param cbWrite Nr of bytes to write * */ -VMMRCDECL(int) PATMGCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite) +VMMRCDECL(int) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite) { RTGCUINTPTR pWritePageStart, pWritePageEnd; PPATMPATCHPAGE pPatchPage; @@ -147,7 +147,7 @@ VMMRCDECL(int) PATMGCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTR * @param pVM Pointer to the VM. * @param pCtxCore The relevant core context. */ -VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame) +VMMRC_INT_DECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame) { PPATMPATCHREC pRec; PVMCPU pVCpu = VMMGetCpu0(pVM); @@ -185,13 +185,13 @@ VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame) Log(("PATMRC: lookup %x jump table=%x\n", pRegFrame->edx, pRegFrame->edi)); - pRec = PATMQueryFunctionPatch(pVM, (RTRCPTR)(pRegFrame->edx)); + pRec = patmQueryFunctionPatch(pVM, (RTRCPTR)pRegFrame->edx); if (pRec) { if (pRec->patch.uState == PATCH_ENABLED) { RTGCUINTPTR pRelAddr = pRec->patch.pPatchBlockOffset; /* make it relative */ - rc = PATMAddBranchToLookupCache(pVM, (RTRCPTR)pRegFrame->edi, (RTRCPTR)pRegFrame->edx, pRelAddr); + rc = patmAddBranchToLookupCache(pVM, (RTRCPTR)pRegFrame->edi, (RTRCPTR)pRegFrame->edx, pRelAddr); if (rc == VINF_SUCCESS) { Log(("Patch block %RRv called as function\n", pRec->patch.pPrivInstrGC)); @@ -449,7 +449,7 @@ VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame) * @param pVM Pointer to the VM. * @param pCtxCore The relevant core context. */ -VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame) +VMMRC_INT_DECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame) { PPATMPATCHREC pRec; int rc; diff --git a/src/VBox/VMM/VMMRC/PDMRCDevice.cpp b/src/VBox/VMM/VMMRC/PDMRCDevice.cpp index 19d09f61e8f..a5b64e9167e 100644 --- a/src/VBox/VMM/VMMRC/PDMRCDevice.cpp +++ b/src/VBox/VMM/VMMRC/PDMRCDevice.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2011 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; diff --git a/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp b/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp index f153eb6ee74..7004f144191 100644 --- a/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp +++ b/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 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; diff --git a/src/VBox/VMM/include/EMHandleRCTmpl.h b/src/VBox/VMM/include/EMHandleRCTmpl.h index 37f37f7f066..3f3e7753d64 100644 --- a/src/VBox/VMM/include/EMHandleRCTmpl.h +++ b/src/VBox/VMM/include/EMHandleRCTmpl.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2009 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; diff --git a/src/VBox/VMM/include/PATMInternal.h b/src/VBox/VMM/include/PATMInternal.h index d42cf5cdbb4..201eb1c3053 100644 --- a/src/VBox/VMM/include/PATMInternal.h +++ b/src/VBox/VMM/include/PATMInternal.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2012 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; @@ -29,11 +29,13 @@ #include <VBox/log.h> - +/** @name Saved state version numbers. + * @{ */ #define PATM_SSM_VERSION 55 #define PATM_SSM_VERSION_FIXUP_HACK 54 #define PATM_SSM_VERSION_FIXUP_HACK 54 #define PATM_SSM_VERSION_VER16 53 +/** @} */ /* Enable for call patching. */ #define PATM_ENABLE_CALL @@ -553,59 +555,16 @@ DECLCALLBACK(int) patmR3Save(PVM pVM, PSSMHANDLE pSSM); DECLCALLBACK(int) patmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass); #ifdef IN_RING3 -RTRCPTR patmPatchGCPtr2GuestGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t *) pPatchGC); -RTRCPTR patmGuestGCPtrToPatchGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t*) pInstrGC); -RTRCPTR patmGuestGCPtrToClosestPatchGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t*) pInstrGC); +RTRCPTR patmPatchGCPtr2GuestGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t *) pPatchGC); +RTRCPTR patmGuestGCPtrToPatchGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t*) pInstrGC); +RTRCPTR patmGuestGCPtrToClosestPatchGCPtr(PVM pVM, PPATCHINFO pPatch, RCPTRTYPE(uint8_t*) pInstrGC); #endif -/* Add a patch to guest lookup record - * - * @param pVM Pointer to the VM. - * @param pPatch Patch structure ptr - * @param pPatchInstrHC Guest context pointer to patch block - * @param pInstrGC Guest context pointer to privileged instruction - * @param enmType Lookup type - * @param fDirty Dirty flag - * - */ -void patmr3AddP2GLookupRecord(PVM pVM, PPATCHINFO pPatch, uint8_t *pPatchInstrHC, RTRCPTR pInstrGC, PATM_LOOKUP_TYPE enmType, bool fDirty=false); - -/** - * Insert page records for all guest pages that contain instructions that were recompiled for this patch - * - * @returns VBox status code. - * @param pVM Pointer to the VM. - * @param pPatch Patch record - */ -int patmInsertPatchPages(PVM pVM, PPATCHINFO pPatch); - -/** - * Remove page records for all guest pages that contain instructions that were recompiled for this patch - * - * @returns VBox status code. - * @param pVM Pointer to the VM. - * @param pPatch Patch record - */ -int patmRemovePatchPages(PVM pVM, PPATCHINFO pPatch); - -/** - * Returns the GC address of the corresponding patch statistics counter - * - * @returns Stat address - * @param pVM Pointer to the VM. - * @param pPatch Patch structure - */ -RTRCPTR patmPatchQueryStatAddress(PVM pVM, PPATCHINFO pPatch); - -/** - * Remove patch for privileged instruction at specified location - * - * @returns VBox status code. - * @param pVM Pointer to the VM. - * @param pPatchRec Patch record - * @param fForceRemove Remove *all* patches - */ -int PATMRemovePatch(PVM pVM, PPATMPATCHREC pPatchRec, bool fForceRemove); +void patmR3AddP2GLookupRecord(PVM pVM, PPATCHINFO pPatch, uint8_t *pPatchInstrHC, RTRCPTR pInstrGC, + PATM_LOOKUP_TYPE enmType, bool fDirty = false); +int patmInsertPatchPages(PVM pVM, PPATCHINFO pPatch); +RTRCPTR patmPatchQueryStatAddress(PVM pVM, PPATCHINFO pPatch); +int patmR3RemovePatch(PVM pVM, PPATMPATCHREC pPatchRec, bool fForceRemove); /** * Call for analysing the instructions following the privileged instr. for compliance with our heuristics @@ -620,60 +579,14 @@ int PATMRemovePatch(PVM pVM, PPATMPATCHREC pPatchRec, bool fForceRemove); */ typedef int (VBOXCALL *PFN_PATMR3ANALYSE)(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_t *) pInstrGC, RCPTRTYPE(uint8_t *) pCurInstrGC, PPATMP2GLOOKUPREC pCacheRec); -/** - * Install guest OS specific patch - * - * @returns VBox status code. - * @param pVM Pointer to the VM. - * @param pCpu Disassembly state of instruction. - * @param pInstrGC GC Instruction pointer for instruction - * @param pInstrHC GC Instruction pointer for instruction - * @param pPatchRec Patch structure - * - */ -int PATMInstallGuestSpecificPatch(PVM pVM, PDISCPUSTATE pCpu, RTRCPTR pInstrGC, uint8_t *pInstrHC, PPATMPATCHREC pPatchRec); - - -/** - * Check if the instruction is patched as a duplicated function - * - * @returns patch record - * @param pVM Pointer to the VM. - * @param pInstrGC Guest context point to the instruction - * - */ -VMMDECL(PPATMPATCHREC) PATMQueryFunctionPatch(PVM pVM, RTRCPTR pInstrGC); - - -/** - * Empty the specified tree (PV tree, MMR3 heap) - * - * @param pVM Pointer to the VM. - * @param ppTree Tree to empty - */ -void patmEmptyTree(PVM pVM, PPAVLPVNODECORE ppTree); - - -/** - * Empty the specified tree (U32 tree, MMR3 heap) - * - * @param pVM Pointer to the VM. - * @param ppTree Tree to empty - */ -void patmEmptyTreeU32(PVM pVM, PPAVLU32NODECORE ppTree); - - -/** - * Return the name of the patched instruction - * - * @returns instruction name - * - * @param opcode DIS instruction opcode - * @param fPatchFlags Patch flags - */ -VMMDECL(const char *) patmGetInstructionString(uint32_t opcode, uint32_t fPatchFlags); - +int patmR3InstallGuestSpecificPatch(PVM pVM, PDISCPUSTATE pCpu, RTRCPTR pInstrGC, uint8_t *pInstrHC, PPATMPATCHREC pPatchRec); +PPATMPATCHREC patmQueryFunctionPatch(PVM pVM, RTRCPTR pInstrGC); +const char *patmGetInstructionString(uint32_t opcode, uint32_t fPatchFlags); +PPATCHINFO patmFindActivePatchByEntrypoint(PVM pVM, RTRCPTR pInstrGC, bool fIncludeHints = false); +int patmR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu, PPATCHINFO pPatch); +int patmAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR pBranchTarget, RTRCUINTPTR pRelBranchPatch); +R3PTRTYPE(uint8_t *) patmR3GCVirtToHCVirt(PVM pVM, PPATMP2GLOOKUPREC pCacheRec, RCPTRTYPE(uint8_t *) pGCPtr); RT_C_DECLS_BEGIN /** @@ -690,63 +603,7 @@ RT_C_DECLS_BEGIN */ VMMRCDECL(int) PATMGCMonitorPage(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange); -/** - * Find patch for privileged instruction at specified location - * - * @returns Patch structure pointer if found; else NULL - * @param pVM Pointer to the VM. - * @param pInstr Guest context point to instruction that might lie within 5 bytes of an existing patch jump - * @param fIncludeHints Include hinted patches or not - * - */ -PPATCHINFO PATMFindActivePatchByEntrypoint(PVM pVM, RTRCPTR pInstrGC, bool fIncludeHints=false); - -/** - * Patch cli/sti pushf/popf instruction block at specified location - * - * @returns VBox status code. - * @param pVM Pointer to the VM. - * @param pInstrGC Guest context point to privileged instruction - * @param pInstrHC Host context point to privileged instruction - * @param uOpcode Instruction opcodee - * @param uOpSize Size of starting instruction - * @param pPatchRec Patch record - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3PatchBlock(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, - uint32_t uOpcode, uint32_t uOpSize, PPATMPATCHREC pPatchRec); - - -/** - * Replace an instruction with a breakpoint (0xCC), that is handled dynamically in the guest context. - * - * @returns VBox status code. - * @param pVM Pointer to the VM. - * @param pInstrGC Guest context point to privileged instruction - * @param pInstrHC Host context point to privileged instruction - * @param pCpu Disassembly CPU structure ptr - * @param pPatch Patch record - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu, PPATCHINFO pPatch); - -/** - * Mark patch as dirty - * - * @returns VBox status code. - * @param pVM Pointer to the VM. - * @param pPatch Patch record - * - * @note returns failure if patching is not allowed or possible - * - */ -VMMR3DECL(int) PATMR3MarkDirtyPatch(PVM pVM, PPATCHINFO pPatch); - -R3PTRTYPE(uint8_t *) PATMGCVirtToHCVirt(PVM pVM, PPATMP2GLOOKUPREC pCacheRec, RCPTRTYPE(uint8_t *) pGCPtr); +RT_C_DECLS_END /** * Calculate the branch destination @@ -755,7 +612,7 @@ R3PTRTYPE(uint8_t *) PATMGCVirtToHCVirt(PVM pVM, PPATMP2GLOOKUPREC pCacheRec, RC * @param pCpu Disassembly state of instruction. * @param pBranchInstrGC GC pointer of branch instruction */ -inline RTRCPTR PATMResolveBranch(PDISCPUSTATE pCpu, RTRCPTR pBranchInstrGC) +DECLINLINE(RTRCPTR) PATMResolveBranch(PDISCPUSTATE pCpu, RTRCPTR pBranchInstrGC) { uint32_t disp; if (pCpu->Param1.fUse & DISUSE_IMMEDIATE8_REL) @@ -784,8 +641,6 @@ inline RTRCPTR PATMResolveBranch(PDISCPUSTATE pCpu, RTRCPTR pBranchInstrGC) #endif } -RT_C_DECLS_END - #ifdef LOG_ENABLED int patmr3DisasmCallback(PVM pVM, DISCPUSTATE *pCpu, RCPTRTYPE(uint8_t *) pInstrGC, RCPTRTYPE(uint8_t *) pCurInstrGC, PPATMP2GLOOKUPREC pCacheRec); int patmr3DisasmCodeStream(PVM pVM, RCPTRTYPE(uint8_t *) pInstrGC, RCPTRTYPE(uint8_t *) pCurInstrGC, PFN_PATMR3ANALYSE pfnPATMR3Analyse, PPATMP2GLOOKUPREC pCacheRec); diff --git a/src/recompiler/VBoxREMWrapper.cpp b/src/recompiler/VBoxREMWrapper.cpp index 3b1c9fd0338..3db45b79f59 100644 --- a/src/recompiler/VBoxREMWrapper.cpp +++ b/src/recompiler/VBoxREMWrapper.cpp @@ -727,11 +727,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 }, @@ -1248,8 +1243,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 }, |