VirtualBox

Changeset 97199 in vbox for trunk


Ignore:
Timestamp:
Oct 18, 2022 11:37:50 AM (2 years ago)
Author:
vboxsync
Message:

VMM/PGM,IEM,EM: Changed FNPGMRZPHYSPFHANDLER, PGMTrap0eHandler and PGMR0Trap0eHandlerNPMisconfig to take PCPUMCTX instead of PCPUMCTXCORE parameters; dropped PCPUMCTXCORE parameters from IEMExecOneBypassEx, PGMInterpretInstruction and EMInterpretInstruction together with some associated cleanups. [fix]

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r97193 r97199  
    764764 * @param   pVM         The cross context VM structure.
    765765 * @param   pVCpu       The cross context virtual CPU structure.
    766  * @param   pRegFrame   Trap register frame.
     766 * @param   pCtx        Pointer to the register context for the CPU.
    767767 * @param   pDis        The disassembly info for the faulting instruction.
    768768 * @param   pvFault     The fault address.
     
    771771 * @remark  The REP prefix check is left to the caller because of STOSD/W.
    772772 */
    773 DECLINLINE(bool) pgmRZPoolMonitorIsReused(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pDis, RTGCPTR pvFault,
     773DECLINLINE(bool) pgmRZPoolMonitorIsReused(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis, RTGCPTR pvFault,
    774774                                          PPGMPOOLPAGE pPage)
    775775{
     
    784784    /** @todo could make this general, faulting close to rsp should be a safe reuse heuristic. */
    785785    if (   HMHasPendingIrq(pVM)
    786         && pRegFrame->rsp - pvFault < 32)
     786        && pCtx->rsp - pvFault < 32)
    787787    {
    788788        /* Fault caused by stack writes while trying to inject an interrupt event. */
    789         Log(("pgmRZPoolMonitorIsReused: reused %RGv for interrupt stack (rsp=%RGv).\n", pvFault, pRegFrame->rsp));
     789        Log(("pgmRZPoolMonitorIsReused: reused %RGv for interrupt stack (rsp=%RGv).\n", pvFault, pCtx->rsp));
    790790        return true;
    791791    }
    792792
    793     LogFlow(("Reused instr %RGv %d at %RGv param1.fUse=%llx param1.reg=%d\n", pRegFrame->rip, pDis->pCurInstr->uOpcode, pvFault, pDis->Param1.fUse,  pDis->Param1.Base.idxGenReg));
     793    LogFlow(("Reused instr %RGv %d at %RGv param1.fUse=%llx param1.reg=%d\n", pCtx->rip, pDis->pCurInstr->uOpcode, pvFault, pDis->Param1.fUse,  pDis->Param1.Base.idxGenReg));
    794794
    795795    /* Non-supervisor mode write means it's used for something else. */
     
    824824        case OP_STOSWD:
    825825            if (    pDis->fPrefix == (DISPREFIX_REP|DISPREFIX_REX)
    826                 &&  pRegFrame->rcx >= 0x40
     826                &&  pCtx->rcx >= 0x40
    827827               )
    828828            {
     
    881881 * @param   pPage       The pool page (head).
    882882 * @param   pDis        The disassembly of the write instruction.
    883  * @param   pRegFrame   The trap register frame.
     883 * @param   pCtx        Pointer to the register context for the CPU.
    884884 * @param   GCPhysFault The fault address as guest physical address.
    885885 * @param   pvFault     The fault address.
     
    887887 */
    888888static int pgmRZPoolAccessPfHandlerFlush(PVMCC pVM, PVMCPUCC pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
    889                                          PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, RTGCPTR pvFault)
     889                                         PCPUMCTX pCtx, RTGCPHYS GCPhysFault, RTGCPTR pvFault)
    890890{
    891891    NOREF(pVM); NOREF(GCPhysFault);
     
    901901     */
    902902    int rc = VINF_SUCCESS;
    903     VBOXSTRICTRC rc2 = EMInterpretInstructionDisasState(pVCpu, pDis, pRegFrame, pvFault, EMCODETYPE_ALL);
     903    VBOXSTRICTRC rc2 = EMInterpretInstructionDisasState(pVCpu, pDis, CPUMCTX2CORE(pCtx), pvFault, EMCODETYPE_ALL);
    904904    if (rc2 == VINF_SUCCESS)
    905905    { /* do nothing */ }
     
    934934 * @param   pPage       The pool page (head).
    935935 * @param   pDis        The disassembly of the write instruction.
    936  * @param   pRegFrame   The trap register frame.
     936 * @param   pCtx        Pointer to the register context for the CPU.
    937937 * @param   GCPhysFault The fault address as guest physical address.
    938938 * @param   pvFault     The fault address.
    939939 */
    940940DECLINLINE(int) pgmRZPoolAccessPfHandlerSTOSD(PVMCC pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
    941                                               PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, RTGCPTR pvFault)
     941                                              PCPUMCTX pCtx, RTGCPHYS GCPhysFault, RTGCPTR pvFault)
    942942{
    943943    unsigned uIncrement = pDis->Param1.cb;
     
    945945
    946946    Assert(pDis->uCpuMode == DISCPUMODE_32BIT || pDis->uCpuMode == DISCPUMODE_64BIT);
    947     Assert(pRegFrame->rcx <= 0x20);
     947    Assert(pCtx->rcx <= 0x20);
    948948
    949949# ifdef VBOX_STRICT
     
    971971    PVMCPUCC    pVCpu = VMMGetCpu(pPool->CTX_SUFF(pVM));
    972972    RTGCUINTPTR pu32 = (RTGCUINTPTR)pvFault;
    973     while (pRegFrame->rcx)
     973    while (pCtx->rcx)
    974974    {
    975975        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, NULL, uIncrement);
    976         PGMPhysSimpleWriteGCPhys(pVM, GCPhysFault, &pRegFrame->rax, uIncrement);
     976        PGMPhysSimpleWriteGCPhys(pVM, GCPhysFault, &pCtx->rax, uIncrement);
    977977        pu32           += uIncrement;
    978978        GCPhysFault    += uIncrement;
    979         pRegFrame->rdi += uIncrement;
    980         pRegFrame->rcx--;
    981     }
    982     pRegFrame->rip += pDis->cbInstr;
     979        pCtx->rdi += uIncrement;
     980        pCtx->rcx--;
     981    }
     982    pCtx->rip += pDis->cbInstr;
    983983
    984984    LogFlow(("pgmRZPoolAccessPfHandlerSTOSD: returns\n"));
     
    996996 * @param   pPage       The pool page (head).
    997997 * @param   pDis        The disassembly of the write instruction.
    998  * @param   pRegFrame   The trap register frame.
     998 * @param   pCtx        Pointer to the register context for the CPU.
    999999 * @param   GCPhysFault The fault address as guest physical address.
    10001000 * @param   pvFault     The fault address.
     
    10021002 */
    10031003DECLINLINE(int) pgmRZPoolAccessPfHandlerSimple(PVMCC pVM, PVMCPUCC pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
    1004                                                PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, RTGCPTR pvFault, bool *pfReused)
     1004                                               PCPUMCTX pCtx, RTGCPHYS GCPhysFault, RTGCPTR pvFault, bool *pfReused)
    10051005{
    10061006    Log3(("pgmRZPoolAccessPfHandlerSimple\n"));
     
    10361036     * Interpret the instruction.
    10371037     */
    1038     VBOXSTRICTRC rc = EMInterpretInstructionDisasState(pVCpu, pDis, pRegFrame, pvFault, EMCODETYPE_ALL);
     1038    VBOXSTRICTRC rc = EMInterpretInstructionDisasState(pVCpu, pDis, CPUMCTX2CORE(pCtx), pvFault, EMCODETYPE_ALL);
    10391039    if (RT_SUCCESS(rc))
    10401040        AssertMsg(rc == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rc))); /* ASSUMES no complicated stuff here. */
     
    10421042    {
    10431043        LogFlow(("pgmRZPoolAccessPfHandlerSimple: Interpretation failed for %04x:%RGv - opcode=%d\n",
    1044                   pRegFrame->cs.Sel, (RTGCPTR)pRegFrame->rip, pDis->pCurInstr->uOpcode));
     1044                 pCtx->cs.Sel, (RTGCPTR)pCtx->rip, pDis->pCurInstr->uOpcode));
    10451045        rc = VINF_EM_RAW_EMULATE_INSTR;
    10461046        STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitorPf,EmulateInstr));
     
    10881088 * @remarks The @a uUser argument is the index of the PGMPOOLPAGE.
    10891089 */
    1090 DECLCALLBACK(VBOXSTRICTRC) pgmRZPoolAccessPfHandler(PVMCC pVM, PVMCPUCC pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame,
     1090DECLCALLBACK(VBOXSTRICTRC) pgmRZPoolAccessPfHandler(PVMCC pVM, PVMCPUCC pVCpu, RTGCUINT uErrorCode, PCPUMCTX pCtx,
    10911091                                                    RTGCPTR pvFault, RTGCPHYS GCPhysFault, uint64_t uUser)
    10921092{
     
    11851185     */
    11861186    pVCpu->pgm.s.cPoolAccessHandler++;
    1187     if (    pPage->GCPtrLastAccessHandlerRip >= pRegFrame->rip - 0x40      /* observed loops in Windows 7 x64 */
    1188         &&  pPage->GCPtrLastAccessHandlerRip <  pRegFrame->rip + 0x40
     1187    if (    pPage->GCPtrLastAccessHandlerRip >= pCtx->rip - 0x40      /* observed loops in Windows 7 x64 */
     1188        &&  pPage->GCPtrLastAccessHandlerRip <  pCtx->rip + 0x40
    11891189        &&  pvFault == (pPage->GCPtrLastAccessHandlerFault + pDis->Param1.cb)
    11901190        &&  pVCpu->pgm.s.cPoolAccessHandler == pPage->cLastAccessHandler + 1)
     
    12131213             || pgmPoolIsPageLocked(pPage)
    12141214            )
    1215         &&  !(fReused = pgmRZPoolMonitorIsReused(pVM, pVCpu, pRegFrame, pDis, pvFault, pPage))
     1215        &&  !(fReused = pgmRZPoolMonitorIsReused(pVM, pVCpu, pCtx, pDis, pvFault, pPage))
    12161216        &&  !pgmRZPoolMonitorIsForking(pPool, pDis, GCPhysFault & PAGE_OFFSET_MASK))
    12171217    {
     
    12211221        if (!(pDis->fPrefix & (DISPREFIX_REP | DISPREFIX_REPNE)))
    12221222        {
    1223             rc = pgmRZPoolAccessPfHandlerSimple(pVM, pVCpu, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault, &fReused);
     1223            rc = pgmRZPoolAccessPfHandlerSimple(pVM, pVCpu, pPool, pPage, pDis, pCtx, GCPhysFault, pvFault, &fReused);
    12241224            if (fReused)
    12251225                goto flushPage;
     
    12351235                pPage->GCPtrLastAccessHandlerFault = pvFault;
    12361236                pPage->cLastAccessHandler          = pVCpu->pgm.s.cPoolAccessHandler;
    1237                 pPage->GCPtrLastAccessHandlerRip   = pRegFrame->rip;
     1237                pPage->GCPtrLastAccessHandlerRip   = pCtx->rip;
    12381238                /* Make sure we don't kick out a page too quickly. */
    12391239                if (pPage->cModifications > 8)
     
    12611261         */
    12621262        if (    pDis->pCurInstr->uOpcode == OP_STOSWD
    1263             &&  !pRegFrame->eflags.Bits.u1DF
     1263            &&  !pCtx->eflags.Bits.u1DF
    12641264            &&  pDis->uOpMode == pDis->uCpuMode
    12651265            &&  pDis->uAddrMode == pDis->uCpuMode)
     
    12691269            if (    pDis->uCpuMode == DISCPUMODE_32BIT
    12701270                &&  pDis->fPrefix == DISPREFIX_REP
    1271                 &&  pRegFrame->ecx <= 0x20
    1272                 &&  pRegFrame->ecx * 4 <= GUEST_PAGE_SIZE - ((uintptr_t)pvFault & GUEST_PAGE_OFFSET_MASK)
     1271                &&  pCtx->ecx <= 0x20
     1272                &&  pCtx->ecx * 4 <= GUEST_PAGE_SIZE - ((uintptr_t)pvFault & GUEST_PAGE_OFFSET_MASK)
    12731273                &&  !((uintptr_t)pvFault & 3)
    1274                 &&  (pRegFrame->eax == 0 || pRegFrame->eax == 0x80) /* the two values observed. */
     1274                &&  (pCtx->eax == 0 || pCtx->eax == 0x80) /* the two values observed. */
    12751275                )
    12761276            {
    12771277                fValidStosd = true;
    1278                 pRegFrame->rcx &= 0xffffffff;   /* paranoia */
     1278                pCtx->rcx &= 0xffffffff;   /* paranoia */
    12791279            }
    12801280            else
    12811281            if (    pDis->uCpuMode == DISCPUMODE_64BIT
    12821282                &&  pDis->fPrefix == (DISPREFIX_REP | DISPREFIX_REX)
    1283                 &&  pRegFrame->rcx <= 0x20
    1284                 &&  pRegFrame->rcx * 8 <= GUEST_PAGE_SIZE - ((uintptr_t)pvFault & GUEST_PAGE_OFFSET_MASK)
     1283                &&  pCtx->rcx <= 0x20
     1284                &&  pCtx->rcx * 8 <= GUEST_PAGE_SIZE - ((uintptr_t)pvFault & GUEST_PAGE_OFFSET_MASK)
    12851285                &&  !((uintptr_t)pvFault & 7)
    1286                 &&  (pRegFrame->rax == 0 || pRegFrame->rax == 0x80) /* the two values observed. */
     1286                &&  (pCtx->rax == 0 || pCtx->rax == 0x80) /* the two values observed. */
    12871287                )
    12881288            {
     
    12921292            if (fValidStosd)
    12931293            {
    1294                 rc = pgmRZPoolAccessPfHandlerSTOSD(pVM, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault);
     1294                rc = pgmRZPoolAccessPfHandlerSTOSD(pVM, pPool, pPage, pDis, pCtx, GCPhysFault, pvFault);
    12951295                STAM_PROFILE_STOP_EX(&pVM->pgm.s.CTX_SUFF(pPool)->StatMonitorPfRZ, &pPool->StatMonitorPfRZRepStosd, a);
    12961296                PGM_UNLOCK(pVM);
     
    13021302        STAM_COUNTER_INC(&pPool->StatMonitorPfRZRepPrefix);
    13031303        Log4(("pgmRZPoolAccessPfHandler: eax=%#x ecx=%#x edi=%#x esi=%#x rip=%RGv opcode=%d prefix=%#x\n",
    1304               pRegFrame->eax, pRegFrame->ecx, pRegFrame->edi, pRegFrame->esi, (RTGCPTR)pRegFrame->rip, pDis->pCurInstr->uOpcode, pDis->fPrefix));
     1304              pCtx->eax, pCtx->ecx, pCtx->edi, pCtx->esi, (RTGCPTR)pCtx->rip, pDis->pCurInstr->uOpcode, pDis->fPrefix));
    13051305        fNotReusedNotForking = true;
    13061306    }
     
    13141314        &&  (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT || pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_32BIT_PT)
    13151315        &&  (   fNotReusedNotForking
    1316              || (   !pgmRZPoolMonitorIsReused(pVM, pVCpu, pRegFrame, pDis, pvFault, pPage)
     1316             || (   !pgmRZPoolMonitorIsReused(pVM, pVCpu, pCtx, pDis, pvFault, pPage)
    13171317                 && !pgmRZPoolMonitorIsForking(pPool, pDis, GCPhysFault & PAGE_OFFSET_MASK))
    13181318            )
     
    13911391     * the reuse detection must be fixed.
    13921392     */
    1393     rc = pgmRZPoolAccessPfHandlerFlush(pVM, pVCpu, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault);
     1393    rc = pgmRZPoolAccessPfHandlerFlush(pVM, pVCpu, pPool, pPage, pDis, pCtx, GCPhysFault, pvFault);
    13941394    if (    rc == VINF_EM_RAW_EMULATE_INSTR
    13951395        &&  fReused)
     
    13971397        Assert(!PGMPOOL_PAGE_IS_NESTED(pPage)); /* temporary, remove later. */
    13981398        /* Make sure that the current instruction still has shadow page backing, otherwise we'll end up in a loop. */
    1399         if (PGMShwGetPage(pVCpu, pRegFrame->rip, NULL, NULL) == VINF_SUCCESS)
     1399        if (PGMShwGetPage(pVCpu, pCtx->rip, NULL, NULL) == VINF_SUCCESS)
    14001400            rc = VINF_SUCCESS;  /* safe to restart the instruction. */
    14011401    }
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