VirtualBox

Changeset 55937 in vbox for trunk/src/VBox/VMM/VMMRC


Ignore:
Timestamp:
May 19, 2015 2:27:00 PM (10 years ago)
Author:
vboxsync
Message:

CSAM,PATM: Changed csamRCCodePageWritePfHandler to store the pvFault address in pvDirtyFaultPage and made csamR3FlushDirtyPages make it instead of pvDirtyBasePage read-only (+ tell REM about it). Preparing ring-3 access handlers for raw-mode.

Location:
trunk/src/VBox/VMM/VMMRC
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMRC/CSAMRC.cpp

    r55900 r55937  
    7272    PPATMGCSTATE pPATMGCState;
    7373    bool         fPatchCode = PATMIsPatchGCAddr(pVM, pRegFrame->eip);
    74     int          rc;
    7574    NOREF(uErrorCode);
    7675
     
    9695         * Make this particular page R/W.
    9796         */
    98         rc = PGMShwMakePageWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT);
     97        int rc = PGMShwMakePageWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT);
    9998        AssertMsgRC(rc, ("PGMShwModifyPage -> rc=%Rrc\n", rc));
    10099        ASMInvalidatePage((void *)(uintptr_t)pvFault);
     
    114113    if (cpl != 3)
    115114    {
    116         rc = PATMRCHandleWriteToPatchPage(pVM, pRegFrame, (RTRCPTR)((RTRCUINTPTR)pvRange + offRange), 4 /** @todo */);
    117         if (rc == VINF_SUCCESS)
    118             return rc;
    119         if (rc == VINF_EM_RAW_EMULATE_INSTR)
     115        VBOXSTRICTRC rcStrict = PATMRCHandleWriteToPatchPage(pVM, pRegFrame, (RTRCPTR)((RTRCUINTPTR)pvRange + offRange),
     116                                                             4 /** @todo */);
     117        if (rcStrict == VINF_SUCCESS)
     118            return rcStrict;
     119        if (rcStrict == VINF_EM_RAW_EMULATE_INSTR)
    120120        {
    121121            STAM_COUNTER_INC(&pVM->csam.s.StatDangerousWrite);
    122122            return VINF_EM_RAW_EMULATE_INSTR;
    123123        }
    124         Assert(rc == VERR_PATCH_NOT_FOUND);
     124        Assert(rcStrict == VERR_PATCH_NOT_FOUND);
    125125    }
    126126
     
    129129    /* Note that pvFault might be a different address in case of aliases. So use pvRange + offset instead!. */
    130130    pVM->csam.s.pvDirtyBasePage[pVM->csam.s.cDirtyPages] = (RTRCPTR)((RTRCUINTPTR)pvRange + offRange);
    131     pVM->csam.s.pvDirtyFaultPage[pVM->csam.s.cDirtyPages] = (RTRCPTR)((RTRCUINTPTR)pvRange + offRange);
     131    pVM->csam.s.pvDirtyFaultPage[pVM->csam.s.cDirtyPages] = (RTRCPTR)pvFault;
    132132    if (++pVM->csam.s.cDirtyPages == CSAM_MAX_DIRTY_PAGES)
    133133        return VINF_CSAM_PENDING_ACTION;
     
    137137     */
    138138    Log(("csamRCCodePageWriteHandler: enabled r/w for page %RGv\n", pvFault));
    139     rc = PGMShwMakePageWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT);
     139    int rc = PGMShwMakePageWritable(pVCpu, pvFault, PGM_MK_PG_IS_WRITE_FAULT);
    140140    AssertMsgRC(rc, ("PGMShwModifyPage -> rc=%Rrc\n", rc));
    141141    ASMInvalidatePage((void *)(uintptr_t)pvFault);
  • trunk/src/VBox/VMM/VMMRC/PATMRC.cpp

    r55900 r55937  
    6363                                        RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
    6464{
    65     NOREF(pVCpu); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
    66     pVM->patm.s.pvFaultMonitor = (RTRCPTR)(RTRCUINTPTR)pvFault;
     65    NOREF(pVCpu); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange);
     66    Assert(pvUser); Assert(!((uintptr_t)pvUser & PAGE_OFFSET_MASK));
     67    pVM->patm.s.pvFaultMonitor = (RTRCPTR)((uintptr_t)pvUser + (pvFault & PAGE_OFFSET_MASK));
    6768    return VINF_PATM_CHECK_PATCH_PAGE;
    6869}
     
    7374 * (if so, then we are not allowed to turn on r/w)
    7475 *
    75  * @returns VBox status
     76 * @returns Strict VBox status code.
     77 * @retval  VINF_SUCCESS if access interpreted (@a pRegFrame != NULL).
     78 * @retval  VINF_PGM_HANDLER_DO_DEFAULT (@a pRegFrame == NULL).
     79 * @retval  VINF_EM_RAW_EMULATE_INSTR on needing to go to ring-3 to do this.
     80 * @retval  VERR_PATCH_NOT_FOUND if no patch was found.
     81 *
    7682 * @param   pVM         Pointer to the VM.
    77  * @param   pRegFrame   CPU context
    78  * @param   GCPtr       GC pointer to write address
    79  * @param   cbWrite     Nr of bytes to write
     83 * @param   pRegFrame   CPU context if \#PF, NULL if other write..
     84 * @param   GCPtr       GC pointer to write address.
     85 * @param   cbWrite     Number of bytes to write.
    8086 *
    8187 */
    82 VMMRC_INT_DECL(int) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite)
     88VMMRC_INT_DECL(VBOXSTRICTRC) PATMRCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite)
    8389{
    84     RTGCUINTPTR          pWritePageStart, pWritePageEnd;
    85     PPATMPATCHPAGE       pPatchPage;
     90    Assert(cbWrite > 0);
    8691
    8792    /* Quick boundary check */
    88     if (    PAGE_ADDRESS(GCPtr) < PAGE_ADDRESS(pVM->patm.s.pPatchedInstrGCLowest)
    89         ||  PAGE_ADDRESS(GCPtr) > PAGE_ADDRESS(pVM->patm.s.pPatchedInstrGCHighest)
    90        )
    91        return VERR_PATCH_NOT_FOUND;
     93    if (   PAGE_ADDRESS(GCPtr) < PAGE_ADDRESS(pVM->patm.s.pPatchedInstrGCLowest)
     94        || PAGE_ADDRESS(GCPtr) > PAGE_ADDRESS(pVM->patm.s.pPatchedInstrGCHighest))
     95        return VERR_PATCH_NOT_FOUND;
    9296
    9397    STAM_PROFILE_ADV_START(&pVM->patm.s.StatPatchWriteDetect, a);
    9498
    95     pWritePageStart = (RTRCUINTPTR)GCPtr & PAGE_BASE_GC_MASK;
    96     pWritePageEnd   = ((RTRCUINTPTR)GCPtr + cbWrite - 1) & PAGE_BASE_GC_MASK;
    97 
    98     pPatchPage = (PPATMPATCHPAGE)RTAvloU32Get(CTXSUFF(&pVM->patm.s.PatchLookupTree)->PatchTreeByPage, (AVLOU32KEY)pWritePageStart);
     99    /*
     100     * Lookup the patch page record for the write.
     101     */
     102    RTRCUINTPTR pWritePageStart = (RTRCUINTPTR)GCPtr & PAGE_BASE_GC_MASK;
     103    RTRCUINTPTR pWritePageEnd   = ((RTRCUINTPTR)GCPtr + cbWrite - 1) & PAGE_BASE_GC_MASK;
     104
     105    PPATMPATCHPAGE pPatchPage;
     106    pPatchPage = (PPATMPATCHPAGE)RTAvloU32Get(&pVM->patm.s.CTXSUFF(PatchLookupTree)->PatchTreeByPage, pWritePageStart);
    99107    if (    !pPatchPage
    100         &&  pWritePageStart != pWritePageEnd
    101        )
    102     {
    103         pPatchPage = (PPATMPATCHPAGE)RTAvloU32Get(CTXSUFF(&pVM->patm.s.PatchLookupTree)->PatchTreeByPage, (AVLOU32KEY)pWritePageEnd);
    104     }
    105 
    106 #ifdef LOG_ENABLED
    107     if (pPatchPage)
    108         Log(("PATMGCHandleWriteToPatchPage: Found page %RRv for write to %RRv %d bytes (page low:high %RRv:%RRv\n", pPatchPage->Core.Key, GCPtr, cbWrite, pPatchPage->pLowestAddrGC, pPatchPage->pHighestAddrGC));
    109 #endif
    110 
     108        &&  pWritePageStart != pWritePageEnd)
     109        pPatchPage = (PPATMPATCHPAGE)RTAvloU32Get(&pVM->patm.s.CTXSUFF(PatchLookupTree)->PatchTreeByPage, pWritePageEnd);
    111110    if (pPatchPage)
    112111    {
    113         if (    pPatchPage->pLowestAddrGC  > (RTRCPTR)((RTRCUINTPTR)GCPtr + cbWrite - 1)
    114             ||  pPatchPage->pHighestAddrGC < (RTRCPTR)GCPtr)
     112        Log(("PATMGCHandleWriteToPatchPage: Found page %RRv for write to %RRv %d bytes (page low:high %RRv:%RRv\n",
     113             pPatchPage->Core.Key, GCPtr, cbWrite, pPatchPage->pLowestAddrGC, pPatchPage->pHighestAddrGC));
     114        if (   (RTRCUINTPTR)pPatchPage->pLowestAddrGC  > (RTRCUINTPTR)GCPtr + cbWrite - 1U
     115            || (RTRCUINTPTR)pPatchPage->pHighestAddrGC < (RTRCUINTPTR)GCPtr)
    115116        {
    116             /* This part of the page was not patched; try to emulate the instruction. */
     117            /* This part of the page was not patched; try to emulate the instruction / tell the caller to do so. */
     118            if (!pRegFrame)
     119            {
     120                LogFlow(("PATMHandleWriteToPatchPage: Allow writing %RRv LB %#x\n", pRegFrame->eip, GCPtr, cbWrite));
     121                STAM_COUNTER_INC(&pVM->patm.s.StatPatchWriteInterpreted);
     122                STAM_PROFILE_ADV_STOP(&pVM->patm.s.StatPatchWriteDetect, a);
     123                return VINF_PGM_HANDLER_DO_DEFAULT;
     124            }
    117125            LogFlow(("PATMHandleWriteToPatchPage: Interpret %x accessing %RRv\n", pRegFrame->eip, GCPtr));
    118126            int rc = EMInterpretInstruction(VMMGetCpu0(pVM), pRegFrame, (RTGCPTR)(RTRCUINTPTR)GCPtr);
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