VirtualBox

Changeset 49888 in vbox for trunk/src


Ignore:
Timestamp:
Dec 12, 2013 5:03:16 PM (11 years ago)
Author:
vboxsync
Message:

VMM/HMSVMR0: Fix infinite recursion on ring-0 assertion with longjmp callbacks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r49879 r49888  
    19981998    Assert(VMMR0IsLogFlushDisabled(pVCpu));
    19991999
     2000    /*
     2001     * IMPORTANT!!!
     2002     * If you modify code here, make sure to check whether hmR0SvmCallRing3Callback() needs to be updated too.
     2003     */
     2004
    20002005    /* Restore host FPU state if necessary and resync on next R0 reentry .*/
    20012006    if (CPUMIsGuestFPUStateActive(pVCpu))
     
    20552060    }
    20562061
     2062    /*
     2063     * IMPORTANT!!!
     2064     * If you modify code here, make sure to check whether hmR0SvmCallRing3Callback() needs to be updated too.
     2065     */
    20572066    /* Deregister hook now that we've left HM context before re-enabling preemption. */
    20582067    if (VMMR0ThreadCtxHooksAreRegistered(pVCpu))
     
    20922101 * @param   pvUser          The user argument (pointer to the possibly
    20932102 *                          out-of-date guest-CPU context).
    2094  *
    2095  * @remarks Must never be called with @a enmOperation ==
    2096  *          VMMCALLRING3_VM_R0_ASSERTION. We can't assert it here because if it
    2097  *          it -does- get called with VMMCALLRING3_VM_R0_ASSERTION, we'll end up
    2098  *          with an infinite recursion.
    20992103 */
    21002104DECLCALLBACK(int) hmR0SvmCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
    21012105{
    2102     NOREF(enmOperation);
    2103 
    2104     /* VMMRZCallRing3() already makes sure we never get called as a result of an longjmp due to an assertion, */
     2106    if (enmOperation == VMMCALLRING3_VM_R0_ASSERTION)
     2107    {
     2108        /*
     2109         * !!! IMPORTANT !!!
     2110         * If you modify code here, make sure to check whether hmR0SvmLeave() and hmR0SvmLeaveSession() needs
     2111         * to be updated too. This is a stripped down version which gets out ASAP trying to not trigger any assertion.
     2112         */
     2113        VMMRZCallRing3RemoveNotification(pVCpu);
     2114        VMMRZCallRing3Disable(pVCpu);
     2115        HM_DISABLE_PREEMPT_IF_NEEDED();
     2116
     2117        /* Restore host FPU state if necessary and resync on next R0 reentry .*/
     2118        if (CPUMIsGuestFPUStateActive(pVCpu))
     2119            CPUMR0SaveGuestFPU(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
     2120
     2121        /* Restore host debug registers if necessary and resync on next R0 reentry. */
     2122        CPUMR0DebugStateMaybeSaveGuestAndRestoreHost(pVCpu, false /* save DR6 */);
     2123
     2124        /* Deregister hook now that we've left HM context before re-enabling preemption. */
     2125        if (VMMR0ThreadCtxHooksAreRegistered(pVCpu))
     2126            VMMR0ThreadCtxHooksDeregister(pVCpu);
     2127
     2128        /* Leave HM context. This takes care of local init (term). */
     2129        int rc = HMR0LeaveCpu(pVCpu);
     2130
     2131        HM_RESTORE_PREEMPT_IF_NEEDED();
     2132        return VINF_SUCCESS;
     2133    }
     2134
    21052135    Assert(pVCpu);
    21062136    Assert(pvUser);
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