VirtualBox

Changeset 11915 in vbox for trunk


Ignore:
Timestamp:
Sep 1, 2008 12:48:25 PM (16 years ago)
Author:
vboxsync
Message:

First part of 1.6 saved state backwards compatibility (PATM).

File:
1 edited

Legend:

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

    r11902 r11915  
    5656#define PATM_ADD_PTR(a, b)      *(uintptr_t *)&(a) = (uintptr_t)(a) + (uintptr_t)(b)
    5757
     58static void patmCorrectAbsoluteFixup(PVM pVM, PATM &patmInfo, int32_t offset, RTRCPTR *pFixup);
     59
    5860#ifdef VBOX_STRICT
    5961/**
     
    401403#endif
    402404
    403     /** @todo this restriction could be removed as we relocate when loading the saved state,.. */
    404     if (    pVM->patm.s.pGCStateGC != patmInfo.pGCStateGC
    405         ||  pVM->patm.s.pCPUMCtxGC != patmInfo.pCPUMCtxGC
    406         ||  pVM->patm.s.pStatsGC   != patmInfo.pStatsGC)
    407     {
    408         if (SSMR3HandleGetAfter(pSSM) == SSMAFTER_DEBUG_IT) /* hack for x86 / amd64 mix. */
    409             return VINF_SUCCESS;
    410         AssertMsgFailed(("GC state, stat or cpum ptrs don't match (state %VRv:%VRv, cpum %VRv:%VRv, stats %VRv:%VRv!!!\n", pVM->patm.s.pGCStateGC, patmInfo.pGCStateGC, pVM->patm.s.pCPUMCtxGC, patmInfo.pCPUMCtxGC, pVM->patm.s.pStatsGC, patmInfo.pStatsGC));
    411         return VERR_SSM_INVALID_STATE;
    412     }
    413 
    414     /* Relative calls are made to the helper functions. Therefor their location must not change! */
    415     if (    pVM->patm.s.pfnHelperCallGC != patmInfo.pfnHelperCallGC
    416         ||  pVM->patm.s.pfnHelperRetGC  != patmInfo.pfnHelperRetGC
    417         ||  pVM->patm.s.pfnHelperJumpGC != patmInfo.pfnHelperJumpGC
    418         ||  pVM->patm.s.pfnHelperIretGC != patmInfo.pfnHelperIretGC)
     405    /* Relative calls are made to the helper functions. Therefor their relative location must not change! */
     406    /* Note: we reuse the saved global helpers and assume they are identical, which is kind of dangerous. */
     407    if (    (pVM->patm.s.pfnHelperCallGC - pVM->patm.s.pPatchMemGC) != (patmInfo.pfnHelperCallGC  - patmInfo.pPatchMemGC)
     408        ||  (pVM->patm.s.pfnHelperRetGC  - pVM->patm.s.pPatchMemGC) != (patmInfo.pfnHelperRetGC   - patmInfo.pPatchMemGC)
     409        ||  (pVM->patm.s.pfnHelperJumpGC - pVM->patm.s.pPatchMemGC) != (patmInfo.pfnHelperJumpGC  - patmInfo.pPatchMemGC)
     410        ||  (pVM->patm.s.pfnHelperIretGC - pVM->patm.s.pPatchMemGC) != (patmInfo.pfnHelperIretGC  - patmInfo.pPatchMemGC))
    419411    {
    420412        AssertMsgFailed(("Helper function ptrs don't match!!!\n"));
     
    422414    }
    423415
    424     if (    pVM->patm.s.pPatchMemGC != patmInfo.pPatchMemGC
    425         ||  pVM->patm.s.cbPatchMem != patmInfo.cbPatchMem)
     416    if (pVM->patm.s.cbPatchMem != patmInfo.cbPatchMem)
    426417    {
    427418        AssertMsgFailed(("Patch memory ptrs and/or sizes don't match!!!\n"));
     
    538529     * Restore PATM stack page
    539530     */
    540     if (pVM->patm.s.pGCStackGC != patmInfo.pGCStackGC)
    541     {
    542         AssertMsgFailed(("GC patch stack ptrs don't match!!!\n"));
    543         return VERR_SSM_INVALID_STATE;
    544     }
    545531    rc = SSMR3GetMem(pSSM, pVM->patm.s.pGCStackHC, PATM_STACK_TOTAL_SIZE);
    546532    AssertRCReturn(rc, rc);
     
    598584        {
    599585            RELOCREC rec;
     586            int32_t offset;
     587            RTRCPTR *pFixup;
    600588
    601589            rc = SSMR3GetMem(pSSM, &rec, sizeof(rec));
    602590            AssertRCReturn(rc, rc);
     591
     592            /* rec.pRelocPos now contains the relative position inside the hypervisor area. */
     593            offset = (int32_t)rec.pRelocPos;
     594            /* Convert to HC pointer again. */
    603595            PATM_ADD_PTR(rec.pRelocPos, pVM->patm.s.pPatchMemHC);
     596            pFixup = (RTRCPTR *)rec.pRelocPos;
     597
     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);
    604601
    605602            rc = patmPatchAddReloc32(pVM, &pPatchRec->patch, rec.pRelocPos, rec.uType, rec.pSource, rec.pDest);
     
    636633    }
    637634
     635    /*
     636     * Correct absolute fixups in the global patch. (helper functions)
     637     * Bit of a mess. Uses the new patch record, but restored patch functions.
     638     */
     639    PRELOCREC pRec = 0;
     640    AVLPVKEY  key  = 0;
     641
     642    while (true)
     643    {
     644        int32_t offset;
     645        RTRCPTR *pFixup;
     646
     647        /* Get the record that's closest from above */
     648        pRec = (PRELOCREC)RTAvlPVGetBestFit(&pVM->patm.s.pGlobalPatchRec->patch.FixupTree, key, true);
     649        if (pRec == 0)
     650            break;
     651
     652        key = (AVLPVKEY)(pRec->pRelocPos + 1);   /* search for the next record during the next round. */
     653
     654        /* rec.pRelocPos now contains the relative position inside the hypervisor area. */
     655        offset = (int32_t)(pRec->pRelocPos - pVM->patm.s.pPatchMemHC);
     656        pFixup = (RTRCPTR *)pRec->pRelocPos;
     657
     658        /* Correct absolute fixups that refer to PATM structures in the hypervisor region (their addresses might have changed). */
     659        if (pRec->uType == FIXUP_ABSOLUTE)
     660            patmCorrectAbsoluteFixup(pVM, patmInfo, offset, pFixup);
     661    }
     662
    638663#ifdef VBOX_WITH_STATISTICS
    639664    /*
     
    648673}
    649674
    650 
     675/**
     676 * Correct absolute fixups to predefined hypervisor PATM regions. (their addresses might have changed)
     677 *
     678 * @returns VBox status code.
     679 * @param   pVM             VM Handle.
     680 * @param   patmInfo        Saved PATM structure
     681 * @param   offset          Offset of referenced data/code
     682 * @param   pFixup          Fixup address
     683 */
     684static void patmCorrectAbsoluteFixup(PVM pVM, PATM &patmInfo, int32_t offset, RTRCPTR *pFixup)
     685{
     686    if (    patmInfo.pPatchMemGC + offset >= patmInfo.pGCStateGC
     687        &&  patmInfo.pPatchMemGC + offset <  patmInfo.pGCStateGC + sizeof(PATMGCSTATE))
     688    {
     689        LogFlow(("Changing absolute GCState from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC));
     690        *pFixup = (*pFixup - patmInfo.pGCStateGC) + pVM->patm.s.pGCStateGC;
     691    }
     692    else
     693    if (    patmInfo.pPatchMemGC + offset >= patmInfo.pCPUMCtxGC
     694        &&  patmInfo.pPatchMemGC + offset <  patmInfo.pCPUMCtxGC + sizeof(CPUMCTX))
     695    {
     696        LogFlow(("Changing absolute CPUMCTX from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC));
     697        *pFixup = (*pFixup - patmInfo.pCPUMCtxGC) + pVM->patm.s.pCPUMCtxGC;
     698    }
     699    else
     700    if (    patmInfo.pPatchMemGC + offset >= patmInfo.pStatsGC
     701        &&  patmInfo.pPatchMemGC + offset <  patmInfo.pStatsGC + sizeof(CPUMCTX))
     702    {
     703        LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC));
     704        *pFixup = (*pFixup - patmInfo.pStatsGC) + pVM->patm.s.pStatsGC;
     705    }
     706    else
     707    if (    patmInfo.pPatchMemGC + offset >= patmInfo.pGCStackGC
     708        &&  patmInfo.pPatchMemGC + offset <  patmInfo.pGCStackGC + PATM_STACK_TOTAL_SIZE)
     709    {
     710        LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC));
     711        *pFixup = (*pFixup - patmInfo.pGCStackGC) + pVM->patm.s.pGCStackGC;
     712    }
     713    else
     714    if (    patmInfo.pPatchMemGC + offset >= patmInfo.pPatchMemGC
     715        &&  patmInfo.pPatchMemGC + offset <  patmInfo.pPatchMemGC + patmInfo.cbPatchMem)
     716    {
     717        LogFlow(("Changing absolute Stats from %VRv (%VRv) to %VRv\n", patmInfo.pPatchMemGC + offset, *pFixup, (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC));
     718        *pFixup = (*pFixup - patmInfo.pPatchMemGC) + pVM->patm.s.pPatchMemGC;
     719    }
     720    else
     721        AssertFailed();
     722}
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