VirtualBox

Changeset 79543 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jul 5, 2019 7:44:55 AM (6 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Nested VMX: bugref:9180 Streamline and clean up some of the exception handling for not so frequently occurring / trapped exceptions.

File:
1 edited

Legend:

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

    r79537 r79543  
    1466614666
    1466714667/**
    14668  * VM-exit exception handler wrapper for generic exceptions. Simply re-injects
    14669  * the exception reported in the VMX transient structure back into the VM.
    14670  *
    14671  * @remarks Requires uExitIntInfo in the VMX transient structure to be
    14672  *          up-to-date.
     14668 * VM-exit exception handler wrapper for generic exceptions.
     14669 *
     14670 * This simply re-injects the exception back into the VM without any special
     14671 * processing.
    1467314672 */
    1467414673static VBOXSTRICTRC hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
    1467514674{
    1467614675    HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     14676
    1467714677#ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
    1467814678    PCVMXVMCSINFO pVmcsInfo = pVmxTransient->pVmcsInfo;
     
    1468714687     * would have been handled while checking exits due to event delivery.
    1468814688     */
    14689     int rc = hmR0VmxReadExitIntErrorCodeVmcs(pVmxTransient);
     14689    int rc = hmR0VmxReadExitIntInfoVmcs(pVmxTransient);
    1469014690    rc    |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
     14691    rc    |= hmR0VmxReadExitIntErrorCodeVmcs(pVmxTransient);
    1469114692    AssertRCReturn(rc, rc);
    14692     Assert(ASMAtomicUoReadU32(&pVmxTransient->fVmcsFieldsRead) & HMVMX_READ_EXIT_INTERRUPTION_INFO);
    14693 
    14694 #ifdef DEBUG_ramshankar
    14695     rc |= hmR0VmxImportGuestState(pVCpu, pVmxTransient->pVmcsInfo, CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_RIP);
    14696     Log(("hmR0VmxExitXcptGeneric: Reinjecting Xcpt. uVector=%#x cs:rip=%#04x:%#RX64\n",
    14697          VMX_EXIT_INT_INFO_VECTOR(pVmxTransient->uExitIntInfo), pCtx->cs.Sel, pCtx->rip));
     14693
     14694    uint8_t const uVector = VMX_EXIT_INT_INFO_VECTOR(pVmxTransient->uExitIntInfo);
     14695
     14696#ifdef HMVMX_ALWAYS_TRAP_ALL_XCPTS
     14697    rc = hmR0VmxImportGuestState(pVCpu, pVmxTransient->pVmcsInfo, CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_RIP);
     14698    AssertRCReturn(rc, rc);
     14699    Log4Func(("Reinjecting Xcpt. uVector=%#x cs:rip=%#04x:%#RX64\n", uVector, pCtx->cs.Sel, pCtx->rip));
    1469814700#endif
    1469914701
     14702#ifdef VBOX_WITH_STATISTICS
     14703    switch (uVector)
     14704    {
     14705        case X86_XCPT_DE:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDE);     break;
     14706        case X86_XCPT_DB:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDB);     break;
     14707        case X86_XCPT_BP:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestBP);     break;
     14708        case X86_XCPT_OF:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestOF);     break;
     14709        case X86_XCPT_BR:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestBR);     break;
     14710        case X86_XCPT_UD:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestUD);     break;
     14711        case X86_XCPT_NM:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestOF);     break;
     14712        case X86_XCPT_DF:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDF);     break;
     14713        case X86_XCPT_TS:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestTS);     break;
     14714        case X86_XCPT_NP:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNP);     break;
     14715        case X86_XCPT_SS:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestSS);     break;
     14716        case X86_XCPT_GP:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestGP);     break;
     14717        case X86_XCPT_PF:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);     break;
     14718        case X86_XCPT_MF:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestMF);     break;
     14719        case X86_XCPT_AC:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestAC);     break;
     14720        case X86_XCPT_XF:   STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXF);     break;
     14721        default:
     14722            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXcpUnk);
     14723            break;
     14724    }
     14725#endif
     14726
     14727    /* We should never call this function for a page-fault, we'd need to pass on the fault address below otherwise. */
     14728    Assert(   uVector != X86_XCPT_PF
     14729           || VMX_EXIT_INT_INFO_TYPE(pVmxTransient->uExitIntInfo) != VMX_EXIT_INT_INFO_TYPE_HW_XCPT);
     14730    NOREF(uVector);
     14731
     14732    /* Re-inject the original exception into the guest. */
    1470014733    hmR0VmxSetPendingEvent(pVCpu, VMX_ENTRY_INT_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntInfo), pVmxTransient->cbInstr,
    1470114734                           pVmxTransient->uExitIntErrorCode, 0 /* GCPtrFaultAddress */);
     
    1479814831            switch (uVector)
    1479914832            {
    14800                 case X86_XCPT_PF: rcStrict = hmR0VmxExitXcptPF(pVCpu, pVmxTransient);      break;
    14801                 case X86_XCPT_GP: rcStrict = hmR0VmxExitXcptGP(pVCpu, pVmxTransient);      break;
    14802                 case X86_XCPT_MF: rcStrict = hmR0VmxExitXcptMF(pVCpu, pVmxTransient);      break;
    14803                 case X86_XCPT_DB: rcStrict = hmR0VmxExitXcptDB(pVCpu, pVmxTransient);      break;
    14804                 case X86_XCPT_BP: rcStrict = hmR0VmxExitXcptBP(pVCpu, pVmxTransient);      break;
    14805                 case X86_XCPT_AC: rcStrict = hmR0VmxExitXcptAC(pVCpu, pVmxTransient);      break;
    14806 
    14807                 case X86_XCPT_NM: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNM);
    14808                                   rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    14809                 case X86_XCPT_XF: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXF);
    14810                                   rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    14811                 case X86_XCPT_DE: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDE);
    14812                                   rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    14813                 case X86_XCPT_UD: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestUD);
    14814                                   rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    14815                 case X86_XCPT_SS: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestSS);
    14816                                   rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    14817                 case X86_XCPT_NP: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNP);
    14818                                   rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
    14819                 case X86_XCPT_TS: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestTS);
    14820                                   rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;
     14833                case X86_XCPT_PF: rcStrict = hmR0VmxExitXcptPF(pVCpu, pVmxTransient);   break;
     14834                case X86_XCPT_GP: rcStrict = hmR0VmxExitXcptGP(pVCpu, pVmxTransient);   break;
     14835                case X86_XCPT_MF: rcStrict = hmR0VmxExitXcptMF(pVCpu, pVmxTransient);   break;
     14836                case X86_XCPT_DB: rcStrict = hmR0VmxExitXcptDB(pVCpu, pVmxTransient);   break;
     14837                case X86_XCPT_BP: rcStrict = hmR0VmxExitXcptBP(pVCpu, pVmxTransient);   break;
     14838                case X86_XCPT_AC: rcStrict = hmR0VmxExitXcptAC(pVCpu, pVmxTransient);   break;
    1482114839                default:
    14822                 {
    14823                     STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXcpUnk);
    14824                     if (pVmcsInfo->RealMode.fRealOnV86Active)
    14825                     {
    14826                         Assert(pVCpu->CTX_SUFF(pVM)->hm.s.vmx.pRealModeTSS);
    14827                         Assert(PDMVmmDevHeapIsEnabled(pVCpu->CTX_SUFF(pVM)));
    14828                         Assert(CPUMIsGuestInRealModeEx(&pVCpu->cpum.GstCtx));
    14829 
    14830                         rc  = hmR0VmxImportGuestState(pVCpu, pVmcsInfo, CPUMCTX_EXTRN_CR0);
    14831                         rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
    14832                         rc |= hmR0VmxReadExitIntErrorCodeVmcs(pVmxTransient);
    14833                         AssertRCReturn(rc, rc);
    14834                         hmR0VmxSetPendingEvent(pVCpu, VMX_ENTRY_INT_INFO_FROM_EXIT_INT_INFO(uExitIntInfo),
    14835                                                pVmxTransient->cbInstr, pVmxTransient->uExitIntErrorCode,
    14836                                                0 /* GCPtrFaultAddress */);
    14837                         rcStrict = VINF_SUCCESS;
    14838                     }
    14839                     else
    14840                     {
    14841                         AssertMsgFailed(("Unexpected VM-exit caused by exception %#x\n", uVector));
    14842                         pVCpu->hm.s.u32HMError = uVector;
    14843                         rcStrict = VERR_VMX_UNEXPECTED_EXCEPTION;
    14844                     }
     14840                    rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient);
    1484514841                    break;
    14846                 }
    1484714842            }
    1484814843            break;
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