VirtualBox

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


Ignore:
Timestamp:
Jun 3, 2019 10:42:40 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
131049
Message:

VMM/HMVMXR0: Nested VMX: bugref:9180 Partial exception/NMI VM-exit handling.

File:
1 edited

Legend:

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

    r78887 r78928  
    412412 * @{
    413413 */
    414 //static FNVMXEXITHANDLER            hmR0VmxExitXcptOrNmi;
     414static FNVMXEXITHANDLER            hmR0VmxExitXcptOrNmiNested;
    415415//static FNVMXEXITHANDLER            hmR0VmxExitExtIntNested;
    416416static FNVMXEXITHANDLER            hmR0VmxExitTripleFaultNested;
     
    88108810            if (   pVmxTransient->fIsNestedGuest
    88118811                && CPUMIsGuestVmxPinCtlsSet(pVCpu, pCtx, VMX_PIN_CTLS_NMI_EXIT))
    8812                 return IEMExecVmxVmexitNmi(pVCpu);
     8812            {
     8813                VBOXSTRICTRC rcStrict = IEMExecVmxVmexitNmi(pVCpu);
     8814                if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
     8815                    return rcStrict;
     8816            }
    88138817#endif
    88148818            hmR0VmxSetPendingXcptNmi(pVCpu);
     
    88238827     * a valid interrupt we -must- deliver the interrupt. We can no longer re-request it from the APIC.
    88248828     */
    8825     else if (  VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
    8826         && !pVCpu->hm.s.fSingleInstruction)
     8829    else if (    VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
     8830             && !pVCpu->hm.s.fSingleInstruction)
    88278831    {
    88288832        Assert(!DBGFIsStepping(pVCpu));
     
    89498953        rcStrict = hmR0VmxInjectEventVmcs(pVCpu, pVmxTransient, &pVCpu->hm.s.Event, fStepping, &fIntrState);
    89508954        AssertRCReturn(VBOXSTRICTRC_VAL(rcStrict), rcStrict);
     8955
     8956        /*
     8957         * If we are executing a nested-guest make sure that we should intercept subsequent
     8958         * events. The one we are injecting might be part of VM-entry.
     8959         */
     8960        if (pVmxTransient->fIsNestedGuest)
     8961            pVCpu->cpum.GstCtx.hwvirt.vmx.fInterceptEvents = true;
    89518962
    89528963        if (uIntType == VMX_ENTRY_INT_INFO_TYPE_EXT_INT)
     
    1026910280    {
    1027010281        Assert(pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_PAUSE_LOOP_EXIT);
    10271         rc |= VMXWriteVmcs32(VMX_VMCS32_CTRL_PLE_GAP,    cPleGapTicks);
     10282        rc |= VMXWriteVmcs32(VMX_VMCS32_CTRL_PLE_GAP, cPleGapTicks);
    1027210283        rc |= VMXWriteVmcs32(VMX_VMCS32_CTRL_PLE_WINDOW, cPleWindowTicks);
    1027310284    }
     
    1261612627        case VMX_EXIT_IO_INSTR:                 return hmR0VmxExitIoInstrNested(pVCpu, pVmxTransient);
    1261712628        case VMX_EXIT_HLT:                      return hmR0VmxExitHltNested(pVCpu, pVmxTransient);
    12618         case VMX_EXIT_RDTSC:                    return hmR0VmxExitRdtscNested(pVCpu, pVmxTransient);
    12619         case VMX_EXIT_RDTSCP:                   return hmR0VmxExitRdtscpNested(pVCpu, pVmxTransient);
     12629        case VMX_EXIT_XCPT_OR_NMI:              return hmR0VmxExitXcptOrNmiNested(pVCpu, pVmxTransient);
     12630
     12631        /*
     12632         * We shouldn't direct host physical interrupts to the nested-guest.
     12633         */
     12634        case VMX_EXIT_EXT_INT:
     12635            return hmR0VmxExitExtInt(pVCpu, pVmxTransient);
    1262012636
    1262112637        /*
     
    1265312669            return hmR0VmxExitInstrWithInfoNested(pVCpu, pVmxTransient);
    1265412670
    12655         /*
    12656          * We shouldn't direct host physical interrupts to the nested-guest.
    12657          */
    12658         case VMX_EXIT_EXT_INT:
    12659             return hmR0VmxExitExtInt(pVCpu, pVmxTransient);
    12660 
     12671        case VMX_EXIT_RDTSC:                    return hmR0VmxExitRdtscNested(pVCpu, pVmxTransient);
     12672        case VMX_EXIT_RDTSCP:                   return hmR0VmxExitRdtscpNested(pVCpu, pVmxTransient);
    1266112673        case VMX_EXIT_RDMSR:                    return hmR0VmxExitRdmsrNested(pVCpu, pVmxTransient);
    1266212674        case VMX_EXIT_WRMSR:                    return hmR0VmxExitWrmsrNested(pVCpu, pVmxTransient);
     
    1266712679        case VMX_EXIT_MTF:                      return hmR0VmxExitMtfNested(pVCpu, pVmxTransient);
    1266812680        case VMX_EXIT_APIC_ACCESS:              return hmR0VmxExitApicAccessNested(pVCpu, pVmxTransient);
    12669 
    12670         /** @todo NSTVMX: APIC-access, Xcpt or NMI, Mov CRx. */
    12671         case VMX_EXIT_XCPT_OR_NMI:
    12672         {
    12673             return hmR0VmxExitErrUnexpected(pVCpu, pVmxTransient);
    12674         }
    12675 
    1267612681        case VMX_EXIT_MOV_CRX:                  return hmR0VmxExitMovCRxNested(pVCpu, pVmxTransient);
    1267712682        case VMX_EXIT_INT_WINDOW:               return hmR0VmxExitIntWindowNested(pVCpu, pVmxTransient);
     
    1305213057
    1305313058/**
    13054  * VM-exit handler for exceptions or NMIs (VMX_EXIT_XCPT_OR_NMI).
     13059 * VM-exit handler for exceptions or NMIs (VMX_EXIT_XCPT_OR_NMI). Conditional
     13060 * VM-exit.
    1305513061 */
    1305613062HMVMX_EXIT_DECL hmR0VmxExitXcptOrNmi(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     
    1577815784/* -=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
    1577915785
     15786/**
     15787 * Nested-guest VM-exit handler for exceptions or NMIs (VMX_EXIT_XCPT_OR_NMI).
     15788 * Conditional VM-exit.
     15789 */
     15790HMVMX_EXIT_DECL hmR0VmxExitXcptOrNmiNested(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     15791{
     15792    HMVMX_VALIDATE_NESTED_EXIT_HANDLER_PARAMS(pVCpu, pVmxTransient);
     15793
     15794    int rc = hmR0VmxReadExitIntInfoVmcs(pVmxTransient);
     15795    AssertRCReturn(rc, rc);
     15796
     15797    Assert(VMX_EXIT_INT_INFO_IS_VALID(pVmxTransient->uExitIntInfo));
     15798    uint32_t const uExtIntType = VMX_EXIT_INT_INFO_TYPE(pVmxTransient->uExitIntInfo);
     15799
     15800    switch (uExtIntType)
     15801    {
     15802        /*
     15803         * We shouldn't direct host physical NMIs to the nested-guest.
     15804         */
     15805        case VMX_EXIT_INT_INFO_TYPE_NMI:
     15806            return hmR0VmxExitHostNmi(pVCpu);
     15807
     15808        case VMX_EXIT_INT_INFO_TYPE_HW_XCPT:
     15809        {
     15810#if 0
     15811            /* Page-faults are subject to masking using its error code. */
     15812            uint32_t fXcptBitmap = pVmcs->u32XcptBitmap;
     15813            if (uVector == X86_XCPT_PF)
     15814            {
     15815                uint32_t const fXcptPFMask  = pVmcs->u32XcptPFMask;
     15816                uint32_t const fXcptPFMatch = pVmcs->u32XcptPFMatch;
     15817                if ((uErrCode & fXcptPFMask) != fXcptPFMatch)
     15818                    fXcptBitmap ^= RT_BIT(X86_XCPT_PF);
     15819            }
     15820
     15821            /* Consult the exception bitmap for all other hardware exceptions. */
     15822            Assert(uVector <= X86_XCPT_LAST);
     15823            if (fXcptBitmap & RT_BIT(uVector))
     15824                fIntercept = true;
     15825#endif
     15826            break;
     15827        }
     15828
     15829        /*
     15830         * This should only happen when "acknowledge external interrupts on VM-exit" is set.
     15831         * We don't set it when executing guests or nested-guests.
     15832         */
     15833        case VMX_EXIT_INT_INFO_TYPE_EXT_INT:
     15834            RT_FALL_THRU();
     15835        default:
     15836        {
     15837            pVCpu->hm.s.u32HMError = pVmxTransient->uExitIntInfo;
     15838            return VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE;
     15839        }
     15840    }
     15841
     15842    return VERR_NOT_IMPLEMENTED;
     15843}
     15844
    1578015845
    1578115846/**
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