VirtualBox

Changeset 20871 in vbox


Ignore:
Timestamp:
Jun 24, 2009 1:56:19 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
49017
Message:

VMM: Make sure there is enough room for a few physical handler notification before we disable ring-3 calls. Partial VMM[GC|R0]CallHost unification.

Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/err.h

    r20869 r20871  
    811811 * @{
    812812 */
    813 /** Reason for leaving GC: Calling host function. */
     813/** Reason for leaving RZ: Calling host function. */
    814814#define VINF_VMM_CALL_HOST                  2700
    815815/** Reason for leaving R0: Hit a ring-0 assertion on EMT. */
     
    817817/** The hyper CR3 differs between PGM and CPUM. */
    818818#define VERR_VMM_HYPER_CR3_MISMATCH         (-2702)
     819/** Reason for leaving RZ: Illegal call to ring-3. */
     820#define VERR_VMM_RING3_CALL_DISABLED        (-2703)
    819821/** @} */
    820822
  • trunk/include/VBox/rem.h

    r20407 r20871  
    5353VMMDECL(void) REMNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
    5454#endif /* IN_RING0 || IN_RC */
     55#ifdef IN_RC
     56VMMDECL(void) REMNotifyHandlerPhysicalFlushIfAlmostFull(PVM pVM, PVMCPU pVCpu);
     57#endif
    5558VMMDECL(void) REMFlushTBs(PVM pVM);
    5659
  • trunk/include/VBox/vmm.h

    r20663 r20871  
    372372VMMRCDECL(void)     VMMGCGuestToHost(PVM pVM, int rc);
    373373VMMRCDECL(int)      VMMGCCallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg);
    374 VMMRCDECL(bool)     VMMGCLogDisable(PVM pVM);
    375 VMMRCDECL(void)     VMMGCLogRestore(PVM pVM, bool fLog);
    376374VMMRCDECL(void)     VMMGCLogFlushIfFull(PVM pVM);
    377375/** @} */
    378376#endif /* IN_RC */
    379377
     378#if defined(IN_RC) || defined(IN_RING0)
     379/** @defgroup grp_vmm_rz    The VMM Raw-Mode and Ring-0 Context API
     380 * @ingroup grp_vmm
     381 * @{
     382 */
     383VMMRZDECL(int)      VMMRZCallRing3(PVM pVM, PVMCPU pVCpu, VMMCALLHOST enmOperation, uint64_t uArg);
     384VMMRZDECL(int)      VMMRZCallRing3NoCpu(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg);
     385VMMRZDECL(void)     VMMRZCallRing3Disable(PVMCPU pVCpu);
     386VMMRZDECL(void)     VMMRZCallRing3Enable(PVMCPU pVCpu);
     387VMMRZDECL(bool)     VMMRZCallRing3IsEnabled(PVMCPU pVCpu);
     388/** @} */
     389#endif
     390
    380391
    381392/** @} */
  • trunk/src/VBox/VMM/EM.cpp

    r20869 r20871  
    827827                        case VERR_VMM_RING0_ASSERTION:
    828828                        case VERR_VMM_HYPER_CR3_MISMATCH:
     829                        case VERR_VMM_RING3_CALL_DISABLED:
    829830                            return rcLast;
    830831                    }
     
    844845                case VERR_VMM_RING0_ASSERTION:
    845846                case VERR_VMM_HYPER_CR3_MISMATCH:
     847                case VERR_VMM_RING3_CALL_DISABLED:
    846848                case VERR_INTERNAL_ERROR:
    847849                case VERR_INTERNAL_ERROR_2:
     
    25742576        case VERR_VMM_RING0_ASSERTION:
    25752577        case VERR_VMM_HYPER_CR3_MISMATCH:
     2578        case VERR_VMM_RING3_CALL_DISABLED:
    25762579            break;
    25772580
  • trunk/src/VBox/VMM/Makefile.kmk

    r20541 r20871  
    322322        VMMGC/HWACCMGCA.asm \
    323323        VMMRZ/DBGFRZ.cpp \
     324        VMMRZ/VMMRZ.cpp \
    324325        VMMAll/CPUMAllRegs.cpp \
    325326        VMMAll/CPUMAllA.asm \
     
    415416        VMMR0/VMMR0.cpp \
    416417        VMMRZ/DBGFRZ.cpp \
     418        VMMRZ/VMMRZ.cpp \
    417419        VMMAll/CPUMAllA.asm \
    418420        VMMAll/CPUMAllRegs.cpp \
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r20795 r20871  
    43654365
    43664366#  ifdef IN_RC
    4367     /* NOTE: We can't deal with jumps to ring 3 here as we're now in an inconsistent state! */
    4368     bool fLog = VMMGCLogDisable(pVM);
     4367    /*
     4368     * WARNING! We can't deal with jumps to ring 3 in the code below as the
     4369     *          state will be inconsistent! Flush important things now while
     4370     *          we still can and then make sure there are no ring-3 calls.
     4371     */
     4372    REMNotifyHandlerPhysicalFlushIfAlmostFull(pVM, pVCpu);
     4373    VMMRZCallRing3Disable(pVCpu);
    43694374#  endif
    43704375
     
    44014406
    44024407#  ifdef IN_RC
    4403     VMMGCLogRestore(pVM, fLog);
     4408    /* NOTE: The state is consistent again. */
     4409    VMMRZCallRing3Enable(pVCpu);
    44044410#  endif
    44054411
  • trunk/src/VBox/VMM/VMMAll/REMAll.cpp

    r20869 r20871  
    2222
    2323/*******************************************************************************
    24 *   Global Variables                                                           *
     24*   Header Files                                                               *
    2525*******************************************************************************/
    2626#define LOG_GROUP LOG_GROUP_REM
     
    8080
    8181/**
    82  * Flushes the handler notifications by calling the host.
    83  *
    84  * @param   pVM     The VM handle.
    85  */
    86 static void remFlushHandlerNotifications(PVM pVM)
    87 {
    88 #ifdef IN_RC
    89     VMMGCCallHost(pVM, VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS, 0);
    90 #elif defined(IN_RING0)
    91     /** @todo necessary? */
    92     VMMR0CallHost(pVM, VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS, 0);
    93 #else
    94     AssertReleaseMsgFailed(("Ring 3 call????.\n"));
    95 #endif
    96 }
    97 
    98 
    99 /**
    10082 * Insert pending notification
    10183 *
     
    120102                Assert(cFlushes++ != 128);
    121103                AssertFatal(cFlushes < _1M);
    122                 remFlushHandlerNotifications(pVM);
     104                VMMRZCallRing3NoCpu(pVM, VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS, 0);
    123105                idxFree = ASMAtomicUoReadU32(&pVM->rem.s.idxFreeList);
    124106            } while (idxFree == (uint32_t)-1);
     
    145127
    146128    VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY);
    147 
    148 #if 0 /* Enable this to trigger odd flush bugs. */
    149     remFlushHandlerNotifications(pVM);
    150 #endif
    151129}
    152130
     
    222200#endif /* !IN_RING3 */
    223201
     202#ifdef IN_RC
     203/**
     204 * Flushes the physical handler notifications if the queue is almost full.
     205 *
     206 * This is for avoiding trouble in RC when changing CR3.
     207 *
     208 * @param   pVM         The VM handle.
     209 * @param   pVCpu       The virtual CPU handle of the calling EMT.
     210 */
     211VMMDECL(void) REMNotifyHandlerPhysicalFlushIfAlmostFull(PVM pVM, PVMCPU pVCpu)
     212{
     213    Assert(pVM->cCPUs == 1);
     214
     215    /*
     216     * Less than 10 items means we should flush.
     217     */
     218    uint32_t cFree = 0;
     219    for (uint32_t idx = pVM->rem.s.idxFreeList;
     220         idx != UINT32_MAX;
     221         idx = pVM->rem.s.aHandlerNotifications[idx].idxNext)
     222    {
     223        Assert(idx < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications));
     224        if (++cFree > 10)
     225            return;
     226    }
     227
     228    /* Ok, we gotta flush them. */
     229    VMMRZCallRing3NoCpu(pVM, VMMCALLHOST_REM_REPLAY_HANDLER_NOTIFICATIONS, 0);
     230}
     231#endif /* IN_RC */
     232
     233
    224234/**
    225235 * Make REM flush all translation block upon the next call to REMR3State().
  • trunk/src/VBox/VMM/VMMGC/VMMGC.cpp

    r19434 r20871  
    190190        &&  pVM->vmm.s.pRCLoggerRC->offScratch >= (sizeof(pVM->vmm.s.pRCLoggerRC->achScratch)*3/4))
    191191    {
     192        if (pVM->vmm.s.fRCLoggerFlushingDisabled)
     193            return; /* fail quietly. */
    192194        VMMGCCallHost(pVM, VMMCALLHOST_VMM_LOGGER_FLUSH, 0);
    193195    }
    194 }
    195 
    196 /**
    197  * Disables the GC logger temporarily, restore with VMMGCLogRestore.
    198  *
    199  * @param   pVM             The VM handle.
    200  */
    201 VMMRCDECL(bool) VMMGCLogDisable(PVM pVM)
    202 {
    203     bool fLog = pVM->vmm.s.pRCLoggerRC
    204              && !(pVM->vmm.s.pRCLoggerRC->fFlags & RTLOGFLAGS_DISABLED);
    205     if (fLog)
    206         pVM->vmm.s.pRCLoggerRC->fFlags |= RTLOGFLAGS_DISABLED;
    207     return fLog;
    208 }
    209 
    210 
    211 /**
    212  * Restores the GC logger after a call to VMMGCLogDisable.
    213  *
    214  * @param   pVM             The VM handle.
    215  * @param   fLog            What VMMGCLogDisable returned.
    216  */
    217 VMMRCDECL(void) VMMGCLogRestore(PVM pVM, bool fLog)
    218 {
    219     if (fLog && pVM->vmm.s.pRCLoggerRC)
    220         pVM->vmm.s.pRCLoggerRC->fFlags &= ~RTLOGFLAGS_DISABLED;
    221196}
    222197
     
    241216 * @param   enmOperation    The operation.
    242217 * @param   uArg            The argument to the operation.
     218 *
     219 * @deprecated Use VMMRZCallRing3.
    243220 */
    244221VMMRCDECL(int) VMMGCCallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg)
    245222{
    246     PVMCPU pVCpu = VMMGetCpu0(pVM);
    247 
    248 /** @todo profile this! */
    249     pVCpu->vmm.s.enmCallHostOperation = enmOperation;
    250     pVCpu->vmm.s.u64CallHostArg = uArg;
    251     pVCpu->vmm.s.rcCallHost = VERR_INTERNAL_ERROR;
    252     pVM->vmm.s.pfnGuestToHostRC(VINF_VMM_CALL_HOST);
    253     return pVCpu->vmm.s.rcCallHost;
     223    return VMMRZCallRing3(pVM, VMMGetCpu0(pVM), enmOperation, uArg);
    254224}
    255225
  • trunk/src/VBox/VMM/VMMGuruMeditation.cpp

    r20869 r20871  
    245245        case VERR_VMM_RING0_ASSERTION:
    246246        case VINF_EM_DBG_HYPER_ASSERTION:
     247        case VERR_VMM_RING3_CALL_DISABLED:
    247248        {
    248249            const char *pszMsg1 = VMMR3GetRZAssertMsg1(pVM);
  • trunk/src/VBox/VMM/VMMInternal.h

    r20854 r20871  
    254254     * This may differ from cbRCLogger. */
    255255    uint32_t                    cbRCRelLogger;
     256    /** Whether log flushing has been disabled or not. */
     257    bool                        fRCLoggerFlushingDisabled;
     258    bool                        afAlignment[7]; /**< Alignment padding. */
    256259    /** @} */
    257260
     
    397400#endif
    398401
    399     /** @name CallHost
     402    /** @name Call Ring-3
     403     * Formerly known as host calls.
    400404     * @{ */
     405    /** The disable counter. */
     406    uint32_t                    cCallRing3Disabled;
    401407    /** The pending operation. */
    402408    VMMCALLHOST                 enmCallHostOperation;
    403409    /** The result of the last operation. */
    404410    int32_t                     rcCallHost;
    405 #if HC_ARCH_BITS == 32
     411#if HC_ARCH_BITS == 64
    406412    uint32_t                    padding;
    407413#endif
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r20854 r20871  
    314314 * @param   enmOperation    The operation.
    315315 * @param   uArg            The argument to the operation.
     316 *
     317 * @deprecated Use VMMRZCallRing3.
    316318 */
    317319VMMR0DECL(int) VMMR0CallHost(PVM pVM, VMMCALLHOST enmOperation, uint64_t uArg)
    318320{
    319     PVMCPU pVCpu = VMMGetCpu(pVM);
    320 
    321 /** @todo profile this! */
    322     pVCpu->vmm.s.enmCallHostOperation = enmOperation;
    323     pVCpu->vmm.s.u64CallHostArg = uArg;
    324     pVCpu->vmm.s.rcCallHost = VERR_INTERNAL_ERROR;
    325     int rc = vmmR0CallHostLongJmp(&pVCpu->vmm.s.CallHostR0JmpBuf, VINF_VMM_CALL_HOST);
    326     if (rc == VINF_SUCCESS)
    327         rc = pVCpu->vmm.s.rcCallHost;
    328     return rc;
     321    return VMMRZCallRing3(pVM, VMMGetCpu(pVM), enmOperation, uArg);
    329322}
    330323
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r20808 r20871  
    903903    GEN_CHECK_OFF(VMM, pRCLoggerR3);
    904904    GEN_CHECK_OFF(VMM, cbRCLogger);
     905    GEN_CHECK_OFF(VMM, fRCLoggerFlushingDisabled);
    905906    GEN_CHECK_OFF(VMM, pYieldTimer);
    906907    GEN_CHECK_OFF(VMM, cYieldResumeMillies);
     
    931932    GEN_CHECK_OFF(VMMCPU, pR0LoggerR3);
    932933#endif
     934    GEN_CHECK_OFF(VMMCPU, cCallRing3Disabled);
    933935    GEN_CHECK_OFF(VMMCPU, enmCallHostOperation);
    934936    GEN_CHECK_OFF(VMMCPU, rcCallHost);
Note: See TracChangeset for help on using the changeset viewer.

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