VirtualBox

Changeset 11925 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Sep 1, 2008 3:03:24 PM (16 years ago)
Author:
vboxsync
Message:

More patm compatibility fixes

Location:
trunk/src/VBox/VMM/PATM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PATM/PATM.cpp

    r11311 r11925  
    8282static int               patmReinit(PVM pVM);
    8383static DECLCALLBACK(int) RelocatePatches(PAVLOU32NODECORE pNode, void *pParam);
    84 static DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
    8584
    8685#ifdef VBOX_WITH_DEBUGGER
     
    819818 * @param   pvUser          User argument.
    820819 */
    821 static DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
     820DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser)
    822821{
    823822    Assert(enmAccessType == PGMACCESSTYPE_WRITE);
  • trunk/src/VBox/VMM/PATM/PATMInternal.h

    r11070 r11925  
    2828#include <VBox/stam.h>
    2929#include <VBox/dis.h>
     30#include <VBox/pgm.h>
    3031#include <iprt/avl.h>
    3132#include <iprt/param.h>
     
    521522DECLCALLBACK(int) patmr3Save(PVM pVM, PSSMHANDLE pSSM);
    522523
     524DECLCALLBACK(int) patmVirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
    523525
    524526/**
  • trunk/src/VBox/VMM/PATM/PATMSSM.cpp

    r11920 r11925  
    5656#define PATM_ADD_PTR(a, b)      *(uintptr_t *)&(a) = (uintptr_t)(a) + (uintptr_t)(b)
    5757
    58 static void patmCorrectAbsoluteFixup(PVM pVM, PATM &patmInfo, int32_t offset, RTRCPTR *pFixup);
     58static void patmCorrectFixup(PVM pVM, PATM &patmInfo, PPATCHINFO pPatch, PRELOCREC pRec, int32_t offset, RTRCPTR *pFixup);
    5959
    6060#ifdef VBOX_STRICT
     
    440440     * Restore patch memory contents
    441441     */
     442    Log(("Restore patch memory: new %VRv old %VRv\n", pVM->patm.s.pPatchMemGC, patmInfo.pPatchMemGC));
    442443    rc = SSMR3GetMem(pSSM, pVM->patm.s.pPatchMemHC, pVM->patm.s.cbPatchMem);
    443444    AssertRCReturn(rc, rc);
     
    596597            pFixup = (RTRCPTR *)rec.pRelocPos;
    597598
    598             /* Correct absolute fixups that refer to PATM structures in the hypervisor region (their addresses might have changed). */
    599             if (rec.uType == FIXUP_ABSOLUTE)
    600                 patmCorrectAbsoluteFixup(pVM, patmInfo, offset, pFixup);
     599            if (pPatchRec->patch.uState != PATCH_REFUSED)
     600            {
     601                if (    rec.uType == FIXUP_REL_JMPTOPATCH
     602                    &&  (pPatchRec->patch.flags & PATMFL_PATCHED_GUEST_CODE))
     603                {
     604                    Assert(pPatchRec->patch.cbPatchJump == SIZEOF_NEARJUMP32 || pPatchRec->patch.cbPatchJump == SIZEOF_NEAR_COND_JUMP32);
     605                    unsigned offset = (pPatchRec->patch.cbPatchJump == SIZEOF_NEARJUMP32) ? 1 : 2;
     606
     607                    Assert(pPatchRec->patch.pPrivInstrHC);
     608                    rec.pRelocPos = pPatchRec->patch.pPrivInstrHC + offset;
     609                    pFixup        = (RTRCPTR *)rec.pRelocPos;
     610                }
     611
     612                patmCorrectFixup(pVM, patmInfo, &pPatchRec->patch, &rec, offset, pFixup);
     613            }
    601614
    602615            rc = patmPatchAddReloc32(pVM, &pPatchRec->patch, rec.pRelocPos, rec.uType, rec.pSource, rec.pDest);
     
    657670        pFixup = (RTRCPTR *)pRec->pRelocPos;
    658671
    659         /* Correct absolute fixups that refer to PATM structures in the hypervisor region (their addresses might have changed). */
    660         if (pRec->uType == FIXUP_ABSOLUTE)
    661             patmCorrectAbsoluteFixup(pVM, patmInfo, offset, pFixup);
     672        /* Correct fixups that refer to PATM structures in the hypervisor region (their addresses might have changed). */
     673        patmCorrectFixup(pVM, patmInfo, &pVM->patm.s.pGlobalPatchRec->patch, pRec, offset, pFixup);
    662674    }
    663675
     
    675687
    676688/**
    677  * Correct absolute fixups to predefined hypervisor PATM regions. (their addresses might have changed)
     689 * Correct fixups to predefined hypervisor PATM regions. (their addresses might have changed)
    678690 *
    679691 * @returns VBox status code.
    680692 * @param   pVM             VM Handle.
    681693 * @param   patmInfo        Saved PATM structure
     694 * @param   pPatch          Patch record
     695 * @param   pRec            Relocation record
    682696 * @param   offset          Offset of referenced data/code
    683697 * @param   pFixup          Fixup address
    684698 */
    685 static void patmCorrectAbsoluteFixup(PVM pVM, PATM &patmInfo, int32_t offset, RTRCPTR *pFixup)
     699static void patmCorrectFixup(PVM pVM, PATM &patmInfo, PPATCHINFO pPatch, PRELOCREC pRec, int32_t offset, RTRCPTR *pFixup)
    686700{
    687     if (    patmInfo.pPatchMemGC + offset >= patmInfo.pGCStateGC
    688         &&  patmInfo.pPatchMemGC + offset <  patmInfo.pGCStateGC + sizeof(PATMGCSTATE))
    689     {
    690         LogFlow(("Changing absolute GCState from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC));
    691         *pFixup = (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC;
    692     }
    693     else
    694     if (    patmInfo.pPatchMemGC + offset >= patmInfo.pCPUMCtxGC
    695         &&  patmInfo.pPatchMemGC + offset <  patmInfo.pCPUMCtxGC + sizeof(CPUMCTX))
    696     {
    697         LogFlow(("Changing absolute CPUMCTX from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC));
    698         *pFixup = (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC;
    699     }
    700     else
    701     if (    patmInfo.pPatchMemGC + offset >= patmInfo.pStatsGC
    702         &&  patmInfo.pPatchMemGC + offset <  patmInfo.pStatsGC + sizeof(CPUMCTX))
    703     {
    704         LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC));
    705         *pFixup = (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC;
    706     }
    707     else
    708     if (    patmInfo.pPatchMemGC + offset >= patmInfo.pGCStackGC
    709         &&  patmInfo.pPatchMemGC + offset <  patmInfo.pGCStackGC + PATM_STACK_TOTAL_SIZE)
    710     {
    711         LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC));
    712         *pFixup = (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC;
    713     }
    714     else
    715     if (    patmInfo.pPatchMemGC + offset >= patmInfo.pPatchMemGC
    716         &&  patmInfo.pPatchMemGC + offset <  patmInfo.pPatchMemGC + patmInfo.cbPatchMem)
    717     {
    718         LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC));
    719         *pFixup = (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC;
    720     }
    721     else
    722         AssertFailed();
    723 }
     701    int32_t delta = pVM->patm.s.pPatchMemGC - patmInfo.pPatchMemGC;
     702
     703    switch (pRec->uType)
     704    {
     705    case FIXUP_ABSOLUTE:
     706    {
     707        if (pRec->pSource && !PATMIsPatchGCAddr(pVM, pRec->pSource))
     708            break;
     709
     710        if (    patmInfo.pPatchMemGC + offset >= patmInfo.pGCStateGC
     711            &&  patmInfo.pPatchMemGC + offset <  patmInfo.pGCStateGC + sizeof(PATMGCSTATE))
     712        {
     713            LogFlow(("Changing absolute GCState from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC));
     714            *pFixup = (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC;
     715        }
     716        else
     717        if (    patmInfo.pPatchMemGC + offset >= patmInfo.pCPUMCtxGC
     718            &&  patmInfo.pPatchMemGC + offset <  patmInfo.pCPUMCtxGC + sizeof(CPUMCTX))
     719        {
     720            LogFlow(("Changing absolute CPUMCTX from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC));
     721            *pFixup = (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC;
     722        }
     723        else
     724        if (    patmInfo.pPatchMemGC + offset >= patmInfo.pStatsGC
     725            &&  patmInfo.pPatchMemGC + offset <  patmInfo.pStatsGC + sizeof(CPUMCTX))
     726        {
     727            LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC));
     728            *pFixup = (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC;
     729        }
     730        else
     731        if (    patmInfo.pPatchMemGC + offset >= patmInfo.pGCStackGC
     732            &&  patmInfo.pPatchMemGC + offset <  patmInfo.pGCStackGC + PATM_STACK_TOTAL_SIZE)
     733        {
     734            LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC));
     735            *pFixup = (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC;
     736        }
     737        else
     738        if (    patmInfo.pPatchMemGC + offset >= patmInfo.pPatchMemGC
     739            &&  patmInfo.pPatchMemGC + offset <  patmInfo.pPatchMemGC + patmInfo.cbPatchMem)
     740        {
     741            LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC));
     742            *pFixup = (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC;
     743        }
     744        else
     745            AssertFailed();
     746        break;
     747    }
     748
     749    case FIXUP_REL_JMPTOPATCH:
     750    {
     751        RTRCPTR pTarget = (RTRCPTR)((RTRCINTPTR)pRec->pDest + delta);
     752
     753        if (    pPatch->uState == PATCH_ENABLED
     754            &&  (pPatch->flags & PATMFL_PATCHED_GUEST_CODE))
     755        {
     756            uint8_t    oldJump[SIZEOF_NEAR_COND_JUMP32];
     757            uint8_t    temp[SIZEOF_NEAR_COND_JUMP32];
     758            RTRCPTR    pJumpOffGC;
     759            RTRCINTPTR displ   = (RTRCINTPTR)pTarget - (RTRCINTPTR)pRec->pSource;
     760            RTRCINTPTR displOld= (RTRCINTPTR)pRec->pDest - (RTRCINTPTR)pRec->pSource;
     761
     762            Log(("Relative fixup (g2p) %08X -> %08X at %08X (source=%08x, target=%08x)\n", *(int32_t*)pRec->pRelocPos, displ, pRec->pRelocPos, pRec->pSource, pRec->pDest));
     763
     764            Assert(pRec->pSource - pPatch->cbPatchJump == pPatch->pPrivInstrGC);
     765#ifdef PATM_RESOLVE_CONFLICTS_WITH_JUMP_PATCHES
     766            if (pPatch->cbPatchJump == SIZEOF_NEAR_COND_JUMP32)
     767            {
     768                Assert(pPatch->flags & PATMFL_JUMP_CONFLICT);
     769
     770                pJumpOffGC = pPatch->pPrivInstrGC + 2;    //two byte opcode
     771                oldJump[0] = pPatch->aPrivInstr[0];
     772                oldJump[1] = pPatch->aPrivInstr[1];
     773                *(RTRCUINTPTR *)&oldJump[2] = displOld;
     774            }
     775            else
     776#endif
     777            if (pPatch->cbPatchJump == SIZEOF_NEARJUMP32)
     778            {
     779                pJumpOffGC = pPatch->pPrivInstrGC + 1;    //one byte opcode
     780                oldJump[0] = 0xE9;
     781                *(RTRCUINTPTR *)&oldJump[1] = displOld;
     782            }
     783            else
     784            {
     785                AssertMsgFailed(("Invalid patch jump size %d\n", pPatch->cbPatchJump));
     786                break;
     787            }
     788            Assert(pPatch->cbPatchJump <= sizeof(temp));
     789
     790            /*
     791             * Read old patch jump and compare it to the one we previously installed
     792             */
     793            int rc = PGMPhysReadGCPtr(pVM, temp, pPatch->pPrivInstrGC, pPatch->cbPatchJump);
     794            Assert(VBOX_SUCCESS(rc) || rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT);
     795
     796            if (rc == VERR_PAGE_NOT_PRESENT || rc == VERR_PAGE_TABLE_NOT_PRESENT)
     797            {
     798                RTRCPTR pPage = pPatch->pPrivInstrGC & PAGE_BASE_GC_MASK;
     799
     800                rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_ALL, pPage, pPage + (PAGE_SIZE - 1) /* inclusive! */, 0, patmVirtPageHandler, "PATMGCMonitorPage", 0, "PATMMonitorPatchJump");
     801                Assert(VBOX_SUCCESS(rc) || rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT);
     802            }
     803            else
     804            if (memcmp(temp, oldJump, pPatch->cbPatchJump))
     805            {
     806                Log(("PATM: Patch jump was overwritten -> disabling patch!!\n"));
     807                /*
     808                 * Disable patch; this is not a good solution
     809                 */
     810                /* @todo hopefully it was completely overwritten (if the read was successful)!!!! */
     811                pPatch->uState = PATCH_DISABLED;
     812            }
     813            else
     814            if (VBOX_SUCCESS(rc))
     815            {
     816                rc = PGMPhysWriteGCPtrDirty(pVM, pJumpOffGC, &displ, sizeof(displ));
     817                AssertRC(rc);
     818            }
     819            else
     820            {
     821                AssertMsgFailed(("Unexpected error %d from MMR3PhysReadGCVirt\n", rc));
     822            }
     823        }
     824        else
     825        {
     826            Log(("Skip the guest jump to patch code for this disabled patch %08X - %08X\n", pPatch->pPrivInstrHC, pRec->pRelocPos));
     827        }
     828
     829        pRec->pDest = pTarget;
     830        break;
     831    }
     832
     833    case FIXUP_REL_JMPTOGUEST:
     834    {
     835        RTRCPTR    pSource = (RTRCPTR)((RTRCINTPTR)pRec->pSource + delta);
     836        RTRCINTPTR displ   = (RTRCINTPTR)pRec->pDest - (RTRCINTPTR)pSource;
     837
     838        Assert(!(pPatch->flags & PATMFL_GLOBAL_FUNCTIONS));
     839        Log(("Relative fixup (p2g) %08X -> %08X at %08X (source=%08x, target=%08x)\n", *(int32_t*)pRec->pRelocPos, displ, pRec->pRelocPos, pRec->pSource, pRec->pDest));
     840        *(RTRCUINTPTR *)pRec->pRelocPos = displ;
     841        pRec->pSource = pSource;
     842        break;
     843 
     844    }
     845}
     846}
     847
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette