VirtualBox

Changeset 48230 in vbox for trunk/src


Ignore:
Timestamp:
Sep 2, 2013 2:52:50 PM (11 years ago)
Author:
vboxsync
Message:

VMM: Propagate errors properly while leaving HM context.

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

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

    r48218 r48230  
    10741074        {
    10751075            rc = g_HvmR0.pfnDisableCpu(pCpu, pvCpuPage, HCPhysCpuPage);
    1076             AssertRC(rc);
     1076            AssertRCReturn(rc, rc);
    10771077        }
    10781078        else
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r48227 r48230  
    19611961 * @param   pCtx        Pointer to the guest-CPU context.
    19621962 */
    1963 static void hmR0SvmLeaveSession(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
     1963static int hmR0SvmLeaveSession(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
    19641964{
    19651965    HM_DISABLE_PREEMPT_IF_NEEDED();
     
    19811981    /* Leave HM context. This takes care of local init (term). */
    19821982    int rc = HMR0LeaveCpu(pVCpu);
    1983     AssertRC(rc); NOREF(rc);
    19841983
    19851984    HM_RESTORE_PREEMPT_IF_NEEDED();
     1985    return rc;
    19861986}
    19871987
     
    19901990 * Does the necessary state syncing before doing a longjmp to ring-3.
    19911991 *
     1992 * @returns VBox status code.
    19921993 * @param   pVM         Pointer to the VM.
    19931994 * @param   pVCpu       Pointer to the VMCPU.
     
    19961997 * @remarks No-long-jmp zone!!!
    19971998 */
    1998 static void hmR0SvmLongJmpToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
    1999 {
    2000     hmR0SvmLeaveSession(pVM, pVCpu, pCtx);
     1999static int hmR0SvmLongJmpToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
     2000{
     2001    return hmR0SvmLeaveSession(pVM, pVCpu, pCtx);
    20012002}
    20022003
     
    20132014 *
    20142015 * @remarks Must never be called with @a enmOperation ==
    2015  *          VMMCALLRING3_VM_R0_ASSERTION.
    2016  */
    2017 DECLCALLBACK(void) hmR0SvmCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
     2016 *          VMMCALLRING3_VM_R0_ASSERTION. We can't assert it here because if it
     2017 *          it -does- get called with VMMCALLRING3_VM_R0_ASSERTION, we'll end up
     2018 *          with an infinite recursion.
     2019 */
     2020DECLCALLBACK(int) hmR0SvmCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
    20182021{
    20192022    /* VMMRZCallRing3() already makes sure we never get called as a result of an longjmp due to an assertion, */
     
    20272030
    20282031    Log4(("hmR0SvmCallRing3Callback->hmR0SvmLongJmpToRing3\n"));
    2029     hmR0SvmLongJmpToRing3(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
     2032    int rc = hmR0SvmLongJmpToRing3(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
     2033    AssertRCReturn(rc, rc);
    20302034
    20312035    VMMRZCallRing3Enable(pVCpu);
     2036    return VINF_SUCCESS;
    20322037}
    20332038
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r48227 r48230  
    60856085 * (longjmp, preemption, voluntary exits to ring-3) from VT-x.
    60866086 *
     6087 * @returns VBox status code.
    60876088 * @param   pVM         Pointer to the VM.
    60886089 * @param   pVCpu       Pointer to the VMCPU.
     
    60936094 * @remarks No-long-jmp zone!!!
    60946095 */
    6095 static void hmR0VmxLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     6096static int hmR0VmxLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
    60966097{
    60976098    Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
     
    61056106    {
    61066107        int rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
    6107         AssertRC(rc);
     6108        AssertRCReturn(rc, rc);
    61086109        Assert(pVCpu->hm.s.vmx.fUpdatedGuestState == HMVMX_UPDATED_GUEST_ALL);
    61096110    }
     
    61556156    {
    61566157        int rc = VMXClearVmcs(pVCpu->hm.s.vmx.HCPhysVmcs);
    6157         AssertRC(rc);
     6158        AssertRCReturn(rc, rc);
     6159
    61586160        pVCpu->hm.s.vmx.uVmcsState = HMVMX_VMCS_STATE_CLEAR;
    61596161        Log4Func(("Cleared Vmcs. HostCpuId=%u\n", idCpu));
     
    61616163    Assert(!(pVCpu->hm.s.vmx.uVmcsState & HMVMX_VMCS_STATE_LAUNCHED));
    61626164    NOREF(idCpu);
     6165
     6166    return VINF_SUCCESS;
    61636167}
    61646168
     
    61676171 * Leaves the VT-x session.
    61686172 *
     6173 * @returns VBox status code.
    61696174 * @param   pVM         Pointer to the VM.
    61706175 * @param   pVCpu       Pointer to the VMCPU.
     
    61756180 * @remarks No-long-jmp zone!!!
    61766181 */
    6177 DECLINLINE(void) hmR0VmxLeaveSession(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     6182DECLINLINE(int) hmR0VmxLeaveSession(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
    61786183{
    61796184    HM_DISABLE_PREEMPT_IF_NEEDED();
     
    61866191    if (!pVCpu->hm.s.fLeaveDone)
    61876192    {
    6188         hmR0VmxLeave(pVM, pVCpu, pMixedCtx);
     6193        int rc2 = hmR0VmxLeave(pVM, pVCpu, pMixedCtx);
     6194        AssertRCReturn(rc2, rc2);
    61896195        pVCpu->hm.s.fLeaveDone = true;
    61906196    }
     
    61986204    /* Leave HM context. This takes care of local init (term). */
    61996205    int rc = HMR0LeaveCpu(pVCpu);
    6200     AssertRC(rc); NOREF(rc);
    62016206
    62026207    HM_RESTORE_PREEMPT_IF_NEEDED();
     6208
     6209    return rc;
    62036210}
    62046211
     
    62076214 * Does the necessary state syncing before doing a longjmp to ring-3.
    62086215 *
     6216 * @returns VBox status code.
    62096217 * @param   pVM         Pointer to the VM.
    62106218 * @param   pVCpu       Pointer to the VMCPU.
     
    62156223 * @remarks No-long-jmp zone!!!
    62166224 */
    6217 DECLINLINE(void) hmR0VmxLongJmpToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
    6218 {
    6219     hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx);
     6225DECLINLINE(int) hmR0VmxLongJmpToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     6226{
     6227    return hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx);
    62206228}
    62216229
     
    62296237 * executing outside HM (recompiler/IEM).
    62306238 *
     6239 * @returns VBox status code.
    62316240 * @param   pVM         Pointer to the VM.
    62326241 * @param   pVCpu       Pointer to the VMCPU.
     
    62376246 *                      VINF_VMM_UNKNOWN_RING3_CALL.
    62386247 */
    6239 static void hmR0VmxExitToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, int rcExit)
     6248static int hmR0VmxExitToRing3(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, int rcExit)
    62406249{
    62416250    Assert(pVM);
     
    62476256    {
    62486257        /* We've done what is required in hmR0VmxExitErrInvalidGuestState(). We're not going to continue guest execution... */
    6249         return;
     6258        return VINF_SUCCESS;
    62506259    }
    62516260    else if (RT_UNLIKELY(rcExit == VERR_VMX_INVALID_VMCS_PTR))
     
    62556264        pVCpu->hm.s.vmx.LastError.idEnteredCpu    = pVCpu->hm.s.idEnteredCpu;
    62566265        /* LastError.idCurrentCpu was updated in hmR0VmxPreRunGuestCommitted(). */
    6257         return;
     6266        return VINF_SUCCESS;
    62586267    }
    62596268
     
    62706279
    62716280    /* Save guest state and restore host state bits. */
    6272     hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx);
     6281    int rc = hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx);
    62736282    STAM_COUNTER_DEC(&pVCpu->hm.s.StatSwitchLongJmpToR3);
    62746283
     
    62826291                              | CPUM_CHANGED_HIDDEN_SEL_REGS);
    62836292    Assert(pVCpu->hm.s.vmx.fUpdatedGuestState & HMVMX_UPDATED_GUEST_CR0);
    6284     if (    pVM->hm.s.fNestedPaging
    6285         &&  CPUMIsGuestPagingEnabledEx(pMixedCtx))
     6293    if (   pVM->hm.s.fNestedPaging
     6294        && CPUMIsGuestPagingEnabledEx(pMixedCtx))
    62866295    {
    62876296        CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_GLOBAL_TLB_FLUSH);
     
    63106319    VMMRZCallRing3RemoveNotification(pVCpu);
    63116320    VMMRZCallRing3Enable(pVCpu);
     6321
     6322    return rc;
    63126323}
    63136324
     
    63176328 * longjump to ring-3 and possibly get preempted.
    63186329 *
     6330 * @returns VBox status code.
    63196331 * @param   pVCpu           Pointer to the VMCPU.
    63206332 * @param   enmOperation    The operation causing the ring-3 longjump.
    6321  * @param   pvUser          The user argument (pointer to the possibly
    6322  *                          out-of-date guest-CPU context).
     6333 * @param   pvUser          Opaque pointer to the guest-CPU context. The data
     6334 *                          may be out-of-sync. Make sure to update the required
     6335 *                          fields before using them.
    63236336 *
    63246337 * @remarks Must never be called with @a enmOperation ==
    6325  *          VMMCALLRING3_VM_R0_ASSERTION.
    6326  */
    6327 DECLCALLBACK(void) hmR0VmxCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
     6338 *          VMMCALLRING3_VM_R0_ASSERTION. We can't assert it here because if it
     6339 *          it -does- get called with VMMCALLRING3_VM_R0_ASSERTION, we'll end up
     6340 *          with an infinite recursion.
     6341 */
     6342DECLCALLBACK(int) hmR0VmxCallRing3Callback(PVMCPU pVCpu, VMMCALLRING3 enmOperation, void *pvUser)
    63286343{
    63296344    /* VMMRZCallRing3() already makes sure we never get called as a result of an longjmp due to an assertion. */
     
    63376352
    63386353    Log4(("hmR0VmxCallRing3Callback->hmR0VmxLongJmpToRing3 pVCpu=%p idCpu=%RU32\n", pVCpu, pVCpu->idCpu));
    6339     hmR0VmxLongJmpToRing3(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
     6354    int rc = hmR0VmxLongJmpToRing3(pVCpu->CTX_SUFF(pVM), pVCpu, (PCPUMCTX)pvUser);
     6355    AssertRCReturn(rc, rc);
    63406356
    63416357    VMMRZCallRing3Enable(pVCpu);
     6358    return VINF_SUCCESS;
    63426359}
    63436360
     
    77487765        rc = VINF_EM_TRIPLE_FAULT;
    77497766
    7750     hmR0VmxExitToRing3(pVM, pVCpu, pCtx, rc);
     7767    int rc2 = hmR0VmxExitToRing3(pVM, pVCpu, pCtx, rc);
     7768    if (RT_FAILURE(rc2))
     7769    {
     7770        pVCpu->hm.s.u32HMError = rc;
     7771        rc = rc2;
     7772    }
    77517773    Assert(!VMMRZCallRing3IsNotificationSet(pVCpu));
    77527774    return rc;
  • trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp

    r48228 r48230  
    8686    pVM->vmm.s.pfnRCToHost(VINF_VMM_CALL_HOST);
    8787#else
     88    int rc;
    8889    if (   pVCpu->vmm.s.pfnCallRing3CallbackR0
    8990        && enmOperation != VMMCALLRING3_VM_R0_ASSERTION)
    9091    {
    91         pVCpu->vmm.s.pfnCallRing3CallbackR0(pVCpu, enmOperation, pVCpu->vmm.s.pvCallRing3CallbackUserR0);
    92     }
    93     int rc = vmmR0CallRing3LongJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, VINF_VMM_CALL_HOST);
     92        rc = pVCpu->vmm.s.pfnCallRing3CallbackR0(pVCpu, enmOperation, pVCpu->vmm.s.pvCallRing3CallbackUserR0);
     93        if (RT_FAILURE(rc))
     94            return rc;
     95    }
     96    rc = vmmR0CallRing3LongJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, VINF_VMM_CALL_HOST);
    9497    if (RT_FAILURE(rc))
    9598        return rc;
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