VirtualBox

Changeset 68305 in vbox for trunk/src


Ignore:
Timestamp:
Aug 6, 2017 3:21:45 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
117424
Message:

VMM/HMSVMR0: Nested Hw.virt: Exit bits.

File:
1 edited

Legend:

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

    r68301 r68305  
    9797                                                        pVCpu->hm.s.idEnteredCpu, RTMpCpuId()));
    9898
    99 /** Exception bitmap mask for all contributory exceptions.
     99/**
     100 * Exception bitmap mask for all contributory exceptions.
    100101 *
    101102 * Page fault is deliberately excluded here as it's conditional as to whether
     
    104105#define HMSVM_CONTRIBUTORY_XCPT_MASK  (  RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_TS) \
    105106                                       | RT_BIT(X86_XCPT_DE))
     107
     108/**
     109 *  Mandatory/unconditional guest control intercepts.
     110 */
     111#define HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS           (  SVM_CTRL_INTERCEPT_INTR        \
     112                                                         | SVM_CTRL_INTERCEPT_NMI         \
     113                                                         | SVM_CTRL_INTERCEPT_INIT        \
     114                                                         | SVM_CTRL_INTERCEPT_RDPMC       \
     115                                                         | SVM_CTRL_INTERCEPT_CPUID       \
     116                                                         | SVM_CTRL_INTERCEPT_RSM         \
     117                                                         | SVM_CTRL_INTERCEPT_HLT         \
     118                                                         | SVM_CTRL_INTERCEPT_IOIO_PROT   \
     119                                                         | SVM_CTRL_INTERCEPT_MSR_PROT    \
     120                                                         | SVM_CTRL_INTERCEPT_INVLPGA     \
     121                                                         | SVM_CTRL_INTERCEPT_SHUTDOWN    \
     122                                                         | SVM_CTRL_INTERCEPT_FERR_FREEZE \
     123                                                         | SVM_CTRL_INTERCEPT_VMRUN       \
     124                                                         | SVM_CTRL_INTERCEPT_VMMCALL     \
     125                                                         | SVM_CTRL_INTERCEPT_VMLOAD      \
     126                                                         | SVM_CTRL_INTERCEPT_VMSAVE      \
     127                                                         | SVM_CTRL_INTERCEPT_STGI        \
     128                                                         | SVM_CTRL_INTERCEPT_CLGI        \
     129                                                         | SVM_CTRL_INTERCEPT_SKINIT      \
     130                                                         | SVM_CTRL_INTERCEPT_WBINVD      \
     131                                                         | SVM_CTRL_INTERCEPT_MONITOR     \
     132                                                         | SVM_CTRL_INTERCEPT_MWAIT       \
     133                                                         | SVM_CTRL_INTERCEPT_XSETBV)
     134
     135/**
     136 *  Mandatory/unconditional nested-guest control intercepts.
     137 */
     138#define HMSVM_MANDATORY_NESTED_GUEST_CTRL_INTERCEPTS    (  HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS \
     139                                                         | SVM_CTRL_INTERCEPT_SMI)
    106140
    107141/** @name VMCB Clean Bits.
     
    251285static FNSVMEXITHANDLER hmR0SvmExitMwait;
    252286static FNSVMEXITHANDLER hmR0SvmExitShutdown;
     287static FNSVMEXITHANDLER hmR0SvmExitUnexpected;
    253288static FNSVMEXITHANDLER hmR0SvmExitReadCRx;
    254289static FNSVMEXITHANDLER hmR0SvmExitWriteCRx;
     
    705740
    706741        /* Set up unconditional intercepts and conditions. */
    707         pVmcb->ctrl.u64InterceptCtrl = SVM_CTRL_INTERCEPT_INTR         /* External interrupt causes a #VMEXIT. */
    708                                      | SVM_CTRL_INTERCEPT_NMI          /* Non-maskable interrupts causes a #VMEXIT. */
    709                                      | SVM_CTRL_INTERCEPT_INIT         /* INIT signal causes a #VMEXIT. */
    710                                      | SVM_CTRL_INTERCEPT_RDPMC        /* RDPMC causes a #VMEXIT. */
    711                                      | SVM_CTRL_INTERCEPT_CPUID        /* CPUID causes a #VMEXIT. */
    712                                      | SVM_CTRL_INTERCEPT_RSM          /* RSM causes a #VMEXIT. */
    713                                      | SVM_CTRL_INTERCEPT_HLT          /* HLT causes a #VMEXIT. */
    714                                      | SVM_CTRL_INTERCEPT_IOIO_PROT    /* Use the IOPM to cause IOIO #VMEXITs. */
    715                                      | SVM_CTRL_INTERCEPT_MSR_PROT     /* MSR access not covered by MSRPM causes a #VMEXIT.*/
    716                                      | SVM_CTRL_INTERCEPT_INVLPGA      /* INVLPGA causes a #VMEXIT. */
    717                                      | SVM_CTRL_INTERCEPT_SHUTDOWN     /* Shutdown events causes a #VMEXIT. */
    718                                      | SVM_CTRL_INTERCEPT_FERR_FREEZE  /* Intercept "freezing" during legacy FPU handling. */
    719                                      | SVM_CTRL_INTERCEPT_VMRUN        /* VMRUN causes a #VMEXIT. */
    720                                      | SVM_CTRL_INTERCEPT_VMMCALL      /* VMMCALL causes a #VMEXIT. */
    721                                      | SVM_CTRL_INTERCEPT_VMLOAD       /* VMLOAD causes a #VMEXIT. */
    722                                      | SVM_CTRL_INTERCEPT_VMSAVE       /* VMSAVE causes a #VMEXIT. */
    723                                      | SVM_CTRL_INTERCEPT_STGI         /* STGI causes a #VMEXIT. */
    724                                      | SVM_CTRL_INTERCEPT_CLGI         /* CLGI causes a #VMEXIT. */
    725                                      | SVM_CTRL_INTERCEPT_SKINIT       /* SKINIT causes a #VMEXIT. */
    726                                      | SVM_CTRL_INTERCEPT_WBINVD       /* WBINVD causes a #VMEXIT. */
    727                                      | SVM_CTRL_INTERCEPT_MONITOR      /* MONITOR causes a #VMEXIT. */
    728                                      | SVM_CTRL_INTERCEPT_MWAIT        /* MWAIT causes a #VMEXIT. */
    729                                      | SVM_CTRL_INTERCEPT_XSETBV;      /* XSETBV causes a #VMEXIT. */
     742        pVmcb->ctrl.u64InterceptCtrl = HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS;
    730743
    731744        /* CR0, CR4 reads must be intercepted, our shadow values are not necessarily the same as the guest's. */
     
    17441757 * well and handle it accordingly.
    17451758 *
    1746  * @param   pVCpu           The cross context virtual CPU structure.
    17471759 * @param   pVmcb           Pointer to the VM control block.
    17481760 * @param   pVmcbNstGst     Pointer to the nested-guest VM control block.
    17491761 */
    1750 static void hmR0SvmMergeIntercepts(PVMCPU pVCpu, PCSVMVMCB pVmcb, PSVMVMCB pVmcbNstGst)
    1751 {
    1752     RT_NOREF(pVCpu);
    1753 #if 0
     1762static void hmR0SvmMergeIntercepts(PCSVMVMCB pVmcb, PSVMVMCB pVmcbNstGst)
     1763{
    17541764    pVmcbNstGst->ctrl.u16InterceptRdCRx |= pVmcb->ctrl.u16InterceptRdCRx;
    17551765    pVmcbNstGst->ctrl.u16InterceptWrCRx |= pVmcb->ctrl.u16InterceptWrCRx;
    1756     pVmcbNstGst->ctrl.u16InterceptRdDRx |= pVmcb->ctrl.u16InterceptRdDRx;
    1757     pVmcbNstGst->ctrl.u16InterceptWrDRx |= pVmcb->ctrl.u16InterceptWrDRx;
    1758 #endif
     1766
     1767    /** @todo Figure out debugging with nested-guests, till then just intercept
     1768     *        all DR[0-15] accesses. */
     1769    pVmcbNstGst->ctrl.u16InterceptRdDRx |= 0xffff;
     1770    pVmcbNstGst->ctrl.u16InterceptWrDRx |= 0xffff;
     1771
    17591772    pVmcbNstGst->ctrl.u32InterceptXcpt  |= pVmcb->ctrl.u32InterceptXcpt;
    1760     pVmcbNstGst->ctrl.u64InterceptCtrl  |= pVmcb->ctrl.u64InterceptCtrl;
     1773    pVmcbNstGst->ctrl.u64InterceptCtrl  |= pVmcb->ctrl.u64InterceptCtrl
     1774                                        |  HMSVM_MANDATORY_NESTED_GUEST_CTRL_INTERCEPTS;
     1775
     1776    Assert((pVmcbNstGst->ctrl.u64InterceptCtrl & HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS) == HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS);
    17611777}
    17621778#endif
     
    20352051         */
    20362052        PCSVMVMCB pVmcb = pVCpu->hm.s.svm.pVmcb;
    2037         hmR0SvmMergeIntercepts(pVCpu, pVmcb, pVmcbNstGst);
     2053        hmR0SvmMergeIntercepts(pVmcb, pVmcbNstGst);
    20382054
    20392055        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_SVM_NESTED_GUEST);
     
    26152631    Log4(("hmR0SvmSetPendingEvent: u=%#RX64 u8Vector=%#x Type=%#x ErrorCodeValid=%RTbool ErrorCode=%#RX32\n", pEvent->u,
    26162632          pEvent->n.u8Vector, (uint8_t)pEvent->n.u3Type, !!pEvent->n.u1ErrorCodeValid, pEvent->n.u32ErrorCode));
     2633}
     2634
     2635
     2636/**
     2637 * Sets an invalid-opcode (\#UD) exception as pending-for-injection into the VM.
     2638 *
     2639 * @param   pVCpu       The cross context virtual CPU structure.
     2640 */
     2641DECLINLINE(void) hmR0SvmSetPendingXcptUD(PVMCPU pVCpu)
     2642{
     2643    SVMEVENT Event;
     2644    Event.u          = 0;
     2645    Event.n.u1Valid  = 1;
     2646    Event.n.u3Type   = SVM_EVENT_EXCEPTION;
     2647    Event.n.u8Vector = X86_XCPT_UD;
     2648    hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
     2649}
     2650
     2651
     2652/**
     2653 * Sets a debug (\#DB) exception as pending-for-injection into the VM.
     2654 *
     2655 * @param   pVCpu       The cross context virtual CPU structure.
     2656 */
     2657DECLINLINE(void) hmR0SvmSetPendingXcptDB(PVMCPU pVCpu)
     2658{
     2659    SVMEVENT Event;
     2660    Event.u          = 0;
     2661    Event.n.u1Valid  = 1;
     2662    Event.n.u3Type   = SVM_EVENT_EXCEPTION;
     2663    Event.n.u8Vector = X86_XCPT_DB;
     2664    hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
     2665}
     2666
     2667
     2668/**
     2669 * Sets a page fault (\#PF) exception as pending-for-injection into the VM.
     2670 *
     2671 * @param   pVCpu           The cross context virtual CPU structure.
     2672 * @param   pCtx            Pointer to the guest-CPU context.
     2673 * @param   u32ErrCode      The error-code for the page-fault.
     2674 * @param   uFaultAddress   The page fault address (CR2).
     2675 *
     2676 * @remarks This updates the guest CR2 with @a uFaultAddress!
     2677 */
     2678DECLINLINE(void) hmR0SvmSetPendingXcptPF(PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t u32ErrCode, RTGCUINTPTR uFaultAddress)
     2679{
     2680    SVMEVENT Event;
     2681    Event.u                  = 0;
     2682    Event.n.u1Valid          = 1;
     2683    Event.n.u3Type           = SVM_EVENT_EXCEPTION;
     2684    Event.n.u8Vector         = X86_XCPT_PF;
     2685    Event.n.u1ErrorCodeValid = 1;
     2686    Event.n.u32ErrorCode     = u32ErrCode;
     2687
     2688    /* Update CR2 of the guest. */
     2689    if (pCtx->cr2 != uFaultAddress)
     2690    {
     2691        pCtx->cr2 = uFaultAddress;
     2692        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR2);
     2693    }
     2694
     2695    hmR0SvmSetPendingEvent(pVCpu, &Event, uFaultAddress);
     2696}
     2697
     2698
     2699/**
     2700 * Sets a device-not-available (\#NM) exception as pending-for-injection into
     2701 * the VM.
     2702 *
     2703 * @param   pVCpu       The cross context virtual CPU structure.
     2704 */
     2705DECLINLINE(void) hmR0SvmSetPendingXcptNM(PVMCPU pVCpu)
     2706{
     2707    SVMEVENT Event;
     2708    Event.u          = 0;
     2709    Event.n.u1Valid  = 1;
     2710    Event.n.u3Type   = SVM_EVENT_EXCEPTION;
     2711    Event.n.u8Vector = X86_XCPT_NM;
     2712    hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
     2713}
     2714
     2715
     2716/**
     2717 * Sets a math-fault (\#MF) exception as pending-for-injection into the VM.
     2718 *
     2719 * @param   pVCpu       The cross context virtual CPU structure.
     2720 */
     2721DECLINLINE(void) hmR0SvmSetPendingXcptMF(PVMCPU pVCpu)
     2722{
     2723    SVMEVENT Event;
     2724    Event.u          = 0;
     2725    Event.n.u1Valid  = 1;
     2726    Event.n.u3Type   = SVM_EVENT_EXCEPTION;
     2727    Event.n.u8Vector = X86_XCPT_MF;
     2728    hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
     2729}
     2730
     2731
     2732/**
     2733 * Sets a double fault (\#DF) exception as pending-for-injection into the VM.
     2734 *
     2735 * @param   pVCpu       The cross context virtual CPU structure.
     2736 */
     2737DECLINLINE(void) hmR0SvmSetPendingXcptDF(PVMCPU pVCpu)
     2738{
     2739    SVMEVENT Event;
     2740    Event.u                  = 0;
     2741    Event.n.u1Valid          = 1;
     2742    Event.n.u3Type           = SVM_EVENT_EXCEPTION;
     2743    Event.n.u8Vector         = X86_XCPT_DF;
     2744    Event.n.u1ErrorCodeValid = 1;
     2745    Event.n.u32ErrorCode     = 0;
     2746    hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
    26172747}
    26182748
     
    43444474    switch (pSvmTransient->u64ExitCode)
    43454475    {
    4346 #if 0
    4347         case SVM_EXIT_NPF:
    4348         {
    4349             /** @todo. */
    4350             break;
    4351         }
    4352 #endif
    4353 
    43544476        case SVM_EXIT_CPUID:
    43554477        {
     
    44484570        {
    44494571            Assert(!pVmcbNstGstCtrl->NestedPaging.n.u1NestedPaging);
    4450             return hmR0SvmExecVmexit(pVCpu, pCtx);
     4572            if (pVmcbNstGstCache->u32InterceptXcpt & RT_BIT(X86_XCPT_PF))
     4573                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4574
     4575            /* If the nested-guest isn't for intercepting #PFs, simply forward the #PF to the guest. */
     4576            uint32_t    const u32ErrCode    = pVmcbNstGstCtrl->u64ExitInfo1;
     4577            RTGCUINTPTR const uFaultAddress = pVmcbNstGstCtrl->u64ExitInfo2;
     4578            hmR0SvmSetPendingXcptPF(pVCpu, pCtx, u32ErrCode, uFaultAddress);
     4579            return VINF_SUCCESS;
    44514580        }
    44524581
     
    44744603        {
    44754604            if (pVmcbNstGstCache->u16InterceptRdCRx & (1U << (uint16_t)(pSvmTransient->u64ExitCode - SVM_EXIT_READ_CR0)))
    4476                 hmR0SvmExecVmexit(pVCpu, pCtx);
     4605                return hmR0SvmExecVmexit(pVCpu, pCtx);
    44774606            return hmR0SvmExitReadCRx(pVCpu, pCtx, pSvmTransient);
    44784607        }
     
    44844613        {
    44854614            if (pVmcbNstGstCache->u16InterceptWrCRx & (1U << (uint16_t)(pSvmTransient->u64ExitCode - SVM_EXIT_WRITE_CR0)))
    4486                 hmR0SvmExecVmexit(pVCpu, pCtx);
     4615                return hmR0SvmExecVmexit(pVCpu, pCtx);
    44874616            return hmR0SvmExitWriteCRx(pVCpu, pCtx, pSvmTransient);
    44884617        }
     4618
     4619        case SVM_EXIT_PAUSE:
     4620        {
     4621            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_PAUSE)
     4622                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4623            return hmR0SvmExitPause(pVCpu, pCtx, pSvmTransient);
     4624        }
     4625
     4626        case SVM_EXIT_VINTR:
     4627        {
     4628            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_VINTR)
     4629                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4630            return hmR0SvmExitVIntr(pVCpu, pCtx, pSvmTransient);
     4631        }
     4632
     4633        case SVM_EXIT_INTR:
     4634        {
     4635            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_INTR)
     4636                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4637            return hmR0SvmExitIntr(pVCpu, pCtx, pSvmTransient);
     4638        }
     4639
     4640        case SVM_EXIT_FERR_FREEZE:
     4641        {
     4642            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_FERR_FREEZE)
     4643                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4644            return hmR0SvmExitIntr(pVCpu, pCtx, pSvmTransient);
     4645        }
     4646
     4647        case SVM_EXIT_NMI:
     4648        {
     4649            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_NMI)
     4650                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4651            return hmR0SvmExitIntr(pVCpu, pCtx, pSvmTransient);
     4652        }
     4653
     4654        case SVM_EXIT_INVLPG:
     4655        {
     4656            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_INVLPG)
     4657                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4658            return hmR0SvmExitInvlpg(pVCpu, pCtx, pSvmTransient);
     4659        }
     4660
     4661        case SVM_EXIT_WBINVD:
     4662        {
     4663            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_WBINVD)
     4664                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4665            return hmR0SvmExitWbinvd(pVCpu, pCtx, pSvmTransient);
     4666        }
     4667
     4668        case SVM_EXIT_INVD:
     4669        {
     4670            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_INVD)
     4671                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4672            return hmR0SvmExitInvd(pVCpu, pCtx, pSvmTransient);
     4673        }
     4674
     4675        case SVM_EXIT_RDPMC:
     4676        {
     4677            if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_RDPMC)
     4678                return hmR0SvmExecVmexit(pVCpu, pCtx);
     4679            return hmR0SvmExitRdpmc(pVCpu, pCtx, pSvmTransient);
     4680        }
     4681
     4682        default:
     4683        {
     4684            switch (pSvmTransient->u64ExitCode)
     4685            {
     4686                case SVM_EXIT_READ_DR0:     case SVM_EXIT_READ_DR1:     case SVM_EXIT_READ_DR2:     case SVM_EXIT_READ_DR3:
     4687                case SVM_EXIT_READ_DR6:     case SVM_EXIT_READ_DR7:     case SVM_EXIT_READ_DR8:     case SVM_EXIT_READ_DR9:
     4688                case SVM_EXIT_READ_DR10:    case SVM_EXIT_READ_DR11:    case SVM_EXIT_READ_DR12:    case SVM_EXIT_READ_DR13:
     4689                case SVM_EXIT_READ_DR14:    case SVM_EXIT_READ_DR15:
     4690                {
     4691                    if (pVmcbNstGstCache->u16InterceptRdDRx & (1U << (uint16_t)(pSvmTransient->u64ExitCode - SVM_EXIT_READ_DR0)))
     4692                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4693                    return hmR0SvmExitReadDRx(pVCpu, pCtx, pSvmTransient);
     4694                }
     4695
     4696                case SVM_EXIT_WRITE_DR0:    case SVM_EXIT_WRITE_DR1:    case SVM_EXIT_WRITE_DR2:    case SVM_EXIT_WRITE_DR3:
     4697                case SVM_EXIT_WRITE_DR6:    case SVM_EXIT_WRITE_DR7:    case SVM_EXIT_WRITE_DR8:    case SVM_EXIT_WRITE_DR9:
     4698                case SVM_EXIT_WRITE_DR10:   case SVM_EXIT_WRITE_DR11:   case SVM_EXIT_WRITE_DR12:   case SVM_EXIT_WRITE_DR13:
     4699                case SVM_EXIT_WRITE_DR14:   case SVM_EXIT_WRITE_DR15:
     4700                {
     4701                    if (pVmcbNstGstCache->u16InterceptWrDRx & (1U << (uint16_t)(pSvmTransient->u64ExitCode - SVM_EXIT_WRITE_DR0)))
     4702                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4703                    return hmR0SvmExitWriteDRx(pVCpu, pCtx, pSvmTransient);
     4704                }
     4705
     4706                /* The exceptions not handled here are already handled individually above (as they occur more frequently). */
     4707                case SVM_EXIT_EXCEPTION_0:     /*case SVM_EXIT_EXCEPTION_1:*/   case SVM_EXIT_EXCEPTION_2:
     4708                /*case SVM_EXIT_EXCEPTION_3:*/   case SVM_EXIT_EXCEPTION_4:     case SVM_EXIT_EXCEPTION_5:
     4709                /*case SVM_EXIT_EXCEPTION_6:*/ /*case SVM_EXIT_EXCEPTION_7:*/   case SVM_EXIT_EXCEPTION_8:
     4710                case SVM_EXIT_EXCEPTION_9:       case SVM_EXIT_EXCEPTION_10:    case SVM_EXIT_EXCEPTION_11:
     4711                case SVM_EXIT_EXCEPTION_12:      case SVM_EXIT_EXCEPTION_13:  /*case SVM_EXIT_EXCEPTION_14:*/
     4712                case SVM_EXIT_EXCEPTION_15:      case SVM_EXIT_EXCEPTION_16:  /*case SVM_EXIT_EXCEPTION_17:*/
     4713                case SVM_EXIT_EXCEPTION_18:      case SVM_EXIT_EXCEPTION_19:    case SVM_EXIT_EXCEPTION_20:
     4714                case SVM_EXIT_EXCEPTION_21:      case SVM_EXIT_EXCEPTION_22:    case SVM_EXIT_EXCEPTION_23:
     4715                case SVM_EXIT_EXCEPTION_24:      case SVM_EXIT_EXCEPTION_25:    case SVM_EXIT_EXCEPTION_26:
     4716                case SVM_EXIT_EXCEPTION_27:      case SVM_EXIT_EXCEPTION_28:    case SVM_EXIT_EXCEPTION_29:
     4717                case SVM_EXIT_EXCEPTION_30:      case SVM_EXIT_EXCEPTION_31:
     4718                {
     4719                    if (pVmcbNstGstCache->u32InterceptXcpt & (1U << (uint32_t)(pSvmTransient->u64ExitCode - SVM_EXIT_EXCEPTION_0)))
     4720                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4721                    /** @todo Write hmR0SvmExitXcptGeneric! */
     4722                    return VERR_NOT_IMPLEMENTED;
     4723                }
     4724
     4725                case SVM_EXIT_XSETBV:
     4726                {
     4727                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_XSETBV)
     4728                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4729                    return hmR0SvmExitXsetbv(pVCpu, pCtx, pSvmTransient);
     4730                }
     4731
     4732                case SVM_EXIT_TASK_SWITCH:
     4733                {
     4734                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_TASK_SWITCH)
     4735                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4736                    return hmR0SvmExitTaskSwitch(pVCpu, pCtx, pSvmTransient);
     4737                }
     4738
     4739                case SVM_EXIT_IRET:
     4740                {
     4741                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_IRET)
     4742                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4743                    return hmR0SvmExitIret(pVCpu, pCtx, pSvmTransient);
     4744                }
     4745
     4746                case SVM_EXIT_SHUTDOWN:
     4747                {
     4748                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_SHUTDOWN)
     4749                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4750                    return hmR0SvmExitShutdown(pVCpu, pCtx, pSvmTransient);
     4751                }
     4752
     4753                case SVM_EXIT_SMI:
     4754                {
     4755                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_SMI)
     4756                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4757                    return hmR0SvmExitUnexpected(pVCpu, pCtx, pSvmTransient);
     4758                }
     4759
     4760                case SVM_EXIT_INIT:
     4761                {
     4762                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_INIT)
     4763                        return hmR0SvmExecVmexit(pVCpu, pCtx);
     4764                    return hmR0SvmExitUnexpected(pVCpu, pCtx, pSvmTransient);
     4765                }
     4766
     4767                case SVM_EXIT_VMMCALL:
     4768                {
     4769                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMMCALL)
     4770                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4771                    return hmR0SvmExitVmmCall(pVCpu, pCtx, pSvmTransient);
     4772                }
     4773
     4774                case SVM_EXIT_CLGI:
     4775                {
     4776                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_CLGI)
     4777                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4778                     return hmR0SvmExitClgi(pVCpu, pCtx, pSvmTransient);
     4779                }
     4780
     4781                case SVM_EXIT_STGI:
     4782                {
     4783                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_STGI)
     4784                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4785                     return hmR0SvmExitStgi(pVCpu, pCtx, pSvmTransient);
     4786                }
     4787
     4788                case SVM_EXIT_VMLOAD:
     4789                {
     4790                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMLOAD)
     4791                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4792                    return hmR0SvmExitVmload(pVCpu, pCtx, pSvmTransient);
     4793                }
     4794
     4795                case SVM_EXIT_VMSAVE:
     4796                {
     4797                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMSAVE)
     4798                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4799                    return hmR0SvmExitVmsave(pVCpu, pCtx, pSvmTransient);
     4800                }
     4801
     4802                case SVM_EXIT_INVLPGA:
     4803                {
     4804                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_INVLPGA)
     4805                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4806                    return hmR0SvmExitInvlpga(pVCpu, pCtx, pSvmTransient);
     4807                }
     4808
     4809                case SVM_EXIT_VMRUN:
     4810                {
     4811                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMRUN)
     4812                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4813                    return hmR0SvmExitVmrun(pVCpu, pCtx, pSvmTransient);
     4814                }
     4815
     4816                case SVM_EXIT_RSM:
     4817                {
     4818                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_RSM)
     4819                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4820                    return hmR0SvmExitSetPendingXcptUD(pVCpu, pCtx, pSvmTransient);
     4821                }
     4822
     4823                case SVM_EXIT_SKINIT:
     4824                {
     4825                    if (pVmcbNstGstCache->u64InterceptCtrl & SVM_CTRL_INTERCEPT_SKINIT)
     4826                        hmR0SvmExecVmexit(pVCpu, pCtx);
     4827                    return hmR0SvmExitSetPendingXcptUD(pVCpu, pCtx, pSvmTransient);
     4828                }
     4829
     4830                case SVM_EXIT_NPF:
     4831                {
     4832                    /* We don't yet support nested-paging for nested-guests, so this should never really happen. */
     4833                    Assert(!pVmcbNstGstCtrl->NestedPaging.n.u1NestedPaging);
     4834                    return hmR0SvmExitUnexpected(pVCpu, pCtx, pSvmTransient);
     4835                }
     4836
     4837                default:
     4838                {
     4839                    AssertMsgFailed(("hmR0SvmHandleExitNested: Unknown exit code %#x\n", pSvmTransient->u64ExitCode));
     4840                    pVCpu->hm.s.u32HMError = pSvmTransient->u64ExitCode;
     4841                    return VERR_SVM_UNKNOWN_EXIT;
     4842                }
     4843            }
     4844        }
     4845    }
     4846    /* not reached */
     4847
     4848#undef HM_SVM_HANDLE_XCPT_EXIT_NESTED
     4849}
     4850#endif
     4851
     4852
     4853/**
     4854 * Handles a guest \#VMEXIT (for all EXITCODE values except SVM_EXIT_INVALID).
     4855 *
     4856 * @returns VBox status code (informational status codes included).
     4857 * @param   pVCpu           The cross context virtual CPU structure.
     4858 * @param   pCtx            Pointer to the guest-CPU context.
     4859 * @param   pSvmTransient   Pointer to the SVM transient structure.
     4860 */
     4861static int hmR0SvmHandleExit(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)
     4862{
     4863    Assert(pSvmTransient->u64ExitCode != SVM_EXIT_INVALID);
     4864    Assert(pSvmTransient->u64ExitCode <= SVM_EXIT_MAX);
     4865
     4866    /*
     4867     * The ordering of the case labels is based on most-frequently-occurring #VMEXITs for most guests under
     4868     * normal workloads (for some definition of "normal").
     4869     */
     4870    uint32_t u32ExitCode = pSvmTransient->u64ExitCode;
     4871    switch (pSvmTransient->u64ExitCode)
     4872    {
     4873        case SVM_EXIT_NPF:
     4874            return hmR0SvmExitNestedPF(pVCpu, pCtx, pSvmTransient);
     4875
     4876        case SVM_EXIT_IOIO:
     4877            return hmR0SvmExitIOInstr(pVCpu, pCtx, pSvmTransient);
     4878
     4879        case SVM_EXIT_RDTSC:
     4880            return hmR0SvmExitRdtsc(pVCpu, pCtx, pSvmTransient);
     4881
     4882        case SVM_EXIT_RDTSCP:
     4883            return hmR0SvmExitRdtscp(pVCpu, pCtx, pSvmTransient);
     4884
     4885        case SVM_EXIT_CPUID:
     4886            return hmR0SvmExitCpuid(pVCpu, pCtx, pSvmTransient);
     4887
     4888        case SVM_EXIT_EXCEPTION_14:  /* X86_XCPT_PF */
     4889            return hmR0SvmExitXcptPF(pVCpu, pCtx, pSvmTransient);
     4890
     4891        case SVM_EXIT_EXCEPTION_7:   /* X86_XCPT_NM */
     4892            return hmR0SvmExitXcptNM(pVCpu, pCtx, pSvmTransient);
     4893
     4894        case SVM_EXIT_EXCEPTION_6:   /* X86_XCPT_UD */
     4895            return hmR0SvmExitXcptUD(pVCpu, pCtx, pSvmTransient);
     4896
     4897        case SVM_EXIT_EXCEPTION_16:  /* X86_XCPT_MF */
     4898            return hmR0SvmExitXcptMF(pVCpu, pCtx, pSvmTransient);
     4899
     4900        case SVM_EXIT_EXCEPTION_1:   /* X86_XCPT_DB */
     4901            return hmR0SvmExitXcptDB(pVCpu, pCtx, pSvmTransient);
     4902
     4903        case SVM_EXIT_EXCEPTION_17:  /* X86_XCPT_AC */
     4904            return hmR0SvmExitXcptAC(pVCpu, pCtx, pSvmTransient);
     4905
     4906        case SVM_EXIT_EXCEPTION_3:   /* X86_XCPT_BP */
     4907            return hmR0SvmExitXcptBP(pVCpu, pCtx, pSvmTransient);
     4908
     4909        case SVM_EXIT_MONITOR:
     4910            return hmR0SvmExitMonitor(pVCpu, pCtx, pSvmTransient);
     4911
     4912        case SVM_EXIT_MWAIT:
     4913            return hmR0SvmExitMwait(pVCpu, pCtx, pSvmTransient);
     4914
     4915        case SVM_EXIT_HLT:
     4916            return hmR0SvmExitHlt(pVCpu, pCtx, pSvmTransient);
     4917
     4918        case SVM_EXIT_READ_CR0:
     4919        case SVM_EXIT_READ_CR3:
     4920        case SVM_EXIT_READ_CR4:
     4921            return hmR0SvmExitReadCRx(pVCpu, pCtx, pSvmTransient);
     4922
     4923        case SVM_EXIT_WRITE_CR0:
     4924        case SVM_EXIT_WRITE_CR3:
     4925        case SVM_EXIT_WRITE_CR4:
     4926        case SVM_EXIT_WRITE_CR8:
     4927            return hmR0SvmExitWriteCRx(pVCpu, pCtx, pSvmTransient);
    44894928
    44904929        case SVM_EXIT_PAUSE:
     
    45014940        case SVM_EXIT_NMI:
    45024941            return hmR0SvmExitIntr(pVCpu, pCtx, pSvmTransient);
     4942
     4943        case SVM_EXIT_MSR:
     4944            return hmR0SvmExitMsr(pVCpu, pCtx, pSvmTransient);
    45034945
    45044946        case SVM_EXIT_INVLPG:
     
    45464988                {
    45474989                    /*
    4548                      * We don't intercept NMIs. As for INIT signals, it really shouldn't ever happen here. If it ever does,
    4549                      * we want to know about it so log the exit code and bail.
     4990                     * We don't intercept SMIs. As for INIT signals, it really shouldn't ever happen here.
     4991                     * If it ever does, we want to know about it so log the exit code and bail.
    45504992                     */
    4551                     AssertMsgFailed(("hmR0SvmHandleExitNested: Unexpected exit %#RX32\n", (uint32_t)pSvmTransient->u64ExitCode));
    4552                     pVCpu->hm.s.u32HMError = (uint32_t)pSvmTransient->u64ExitCode;
    4553                     return VERR_SVM_UNEXPECTED_EXIT;
     4993                    return hmR0SvmExitUnexpected(pVCpu, pCtx, pSvmTransient);
    45544994                }
    45554995
     
    46345074
    46355075                        default:
    4636                             AssertMsgFailed(("hmR0SvmHandleExitNested: Unexpected exit caused by exception %#x\n", Event.n.u8Vector));
    4637                             pVCpu->hm.s.u32HMError = Event.n.u8Vector;
    4638                             return VERR_SVM_UNEXPECTED_XCPT_EXIT;
    4639                     }
    4640 
    4641                     Log4(("#Xcpt: Vector=%#x at CS:RIP=%04x:%RGv\n", Event.n.u8Vector, pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
    4642                     hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
    4643                     return VINF_SUCCESS;
    4644                 }
    4645 #endif  /* HMSVM_ALWAYS_TRAP_ALL_XCPTS */
    4646 
    4647                 default:
    4648                 {
    4649                     AssertMsgFailed(("hmR0SvmHandleExitNested: Unknown exit code %#x\n", pSvmTransient->u64ExitCode));
    4650                     pVCpu->hm.s.u32HMError = pSvmTransient->u64ExitCode;
    4651                     return VERR_SVM_UNKNOWN_EXIT;
    4652                 }
    4653             }
    4654         }
    4655     }
    4656     /* not reached */
    4657 
    4658 #undef HM_SVM_HANDLE_XCPT_EXIT_NESTED
    4659 }
    4660 #endif
    4661 
    4662 
    4663 /**
    4664  * Handles a guest \#VMEXIT (for all EXITCODE values except SVM_EXIT_INVALID).
    4665  *
    4666  * @returns VBox status code (informational status codes included).
    4667  * @param   pVCpu           The cross context virtual CPU structure.
    4668  * @param   pCtx            Pointer to the guest-CPU context.
    4669  * @param   pSvmTransient   Pointer to the SVM transient structure.
    4670  */
    4671 static int hmR0SvmHandleExit(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)
    4672 {
    4673     Assert(pSvmTransient->u64ExitCode != SVM_EXIT_INVALID);
    4674     Assert(pSvmTransient->u64ExitCode <= SVM_EXIT_MAX);
    4675 
    4676     /*
    4677      * The ordering of the case labels is based on most-frequently-occurring #VMEXITs for most guests under
    4678      * normal workloads (for some definition of "normal").
    4679      */
    4680     uint32_t u32ExitCode = pSvmTransient->u64ExitCode;
    4681     switch (pSvmTransient->u64ExitCode)
    4682     {
    4683         case SVM_EXIT_NPF:
    4684             return hmR0SvmExitNestedPF(pVCpu, pCtx, pSvmTransient);
    4685 
    4686         case SVM_EXIT_IOIO:
    4687             return hmR0SvmExitIOInstr(pVCpu, pCtx, pSvmTransient);
    4688 
    4689         case SVM_EXIT_RDTSC:
    4690             return hmR0SvmExitRdtsc(pVCpu, pCtx, pSvmTransient);
    4691 
    4692         case SVM_EXIT_RDTSCP:
    4693             return hmR0SvmExitRdtscp(pVCpu, pCtx, pSvmTransient);
    4694 
    4695         case SVM_EXIT_CPUID:
    4696             return hmR0SvmExitCpuid(pVCpu, pCtx, pSvmTransient);
    4697 
    4698         case SVM_EXIT_EXCEPTION_14:  /* X86_XCPT_PF */
    4699             return hmR0SvmExitXcptPF(pVCpu, pCtx, pSvmTransient);
    4700 
    4701         case SVM_EXIT_EXCEPTION_7:   /* X86_XCPT_NM */
    4702             return hmR0SvmExitXcptNM(pVCpu, pCtx, pSvmTransient);
    4703 
    4704         case SVM_EXIT_EXCEPTION_6:   /* X86_XCPT_UD */
    4705             return hmR0SvmExitXcptUD(pVCpu, pCtx, pSvmTransient);
    4706 
    4707         case SVM_EXIT_EXCEPTION_16:  /* X86_XCPT_MF */
    4708             return hmR0SvmExitXcptMF(pVCpu, pCtx, pSvmTransient);
    4709 
    4710         case SVM_EXIT_EXCEPTION_1:   /* X86_XCPT_DB */
    4711             return hmR0SvmExitXcptDB(pVCpu, pCtx, pSvmTransient);
    4712 
    4713         case SVM_EXIT_EXCEPTION_17:  /* X86_XCPT_AC */
    4714             return hmR0SvmExitXcptAC(pVCpu, pCtx, pSvmTransient);
    4715 
    4716         case SVM_EXIT_EXCEPTION_3:   /* X86_XCPT_BP */
    4717             return hmR0SvmExitXcptBP(pVCpu, pCtx, pSvmTransient);
    4718 
    4719         case SVM_EXIT_MONITOR:
    4720             return hmR0SvmExitMonitor(pVCpu, pCtx, pSvmTransient);
    4721 
    4722         case SVM_EXIT_MWAIT:
    4723             return hmR0SvmExitMwait(pVCpu, pCtx, pSvmTransient);
    4724 
    4725         case SVM_EXIT_HLT:
    4726             return hmR0SvmExitHlt(pVCpu, pCtx, pSvmTransient);
    4727 
    4728         case SVM_EXIT_READ_CR0:
    4729         case SVM_EXIT_READ_CR3:
    4730         case SVM_EXIT_READ_CR4:
    4731             return hmR0SvmExitReadCRx(pVCpu, pCtx, pSvmTransient);
    4732 
    4733         case SVM_EXIT_WRITE_CR0:
    4734         case SVM_EXIT_WRITE_CR3:
    4735         case SVM_EXIT_WRITE_CR4:
    4736         case SVM_EXIT_WRITE_CR8:
    4737             return hmR0SvmExitWriteCRx(pVCpu, pCtx, pSvmTransient);
    4738 
    4739         case SVM_EXIT_PAUSE:
    4740             return hmR0SvmExitPause(pVCpu, pCtx, pSvmTransient);
    4741 
    4742         case SVM_EXIT_VMMCALL:
    4743             return hmR0SvmExitVmmCall(pVCpu, pCtx, pSvmTransient);
    4744 
    4745         case SVM_EXIT_VINTR:
    4746             return hmR0SvmExitVIntr(pVCpu, pCtx, pSvmTransient);
    4747 
    4748         case SVM_EXIT_INTR:
    4749         case SVM_EXIT_FERR_FREEZE:
    4750         case SVM_EXIT_NMI:
    4751             return hmR0SvmExitIntr(pVCpu, pCtx, pSvmTransient);
    4752 
    4753         case SVM_EXIT_MSR:
    4754             return hmR0SvmExitMsr(pVCpu, pCtx, pSvmTransient);
    4755 
    4756         case SVM_EXIT_INVLPG:
    4757             return hmR0SvmExitInvlpg(pVCpu, pCtx, pSvmTransient);
    4758 
    4759         case SVM_EXIT_WBINVD:
    4760             return hmR0SvmExitWbinvd(pVCpu, pCtx, pSvmTransient);
    4761 
    4762         case SVM_EXIT_INVD:
    4763             return hmR0SvmExitInvd(pVCpu, pCtx, pSvmTransient);
    4764 
    4765         case SVM_EXIT_RDPMC:
    4766             return hmR0SvmExitRdpmc(pVCpu, pCtx, pSvmTransient);
    4767 
    4768         default:
    4769         {
    4770             switch (pSvmTransient->u64ExitCode)
    4771             {
    4772                 case SVM_EXIT_READ_DR0:     case SVM_EXIT_READ_DR1:     case SVM_EXIT_READ_DR2:     case SVM_EXIT_READ_DR3:
    4773                 case SVM_EXIT_READ_DR6:     case SVM_EXIT_READ_DR7:     case SVM_EXIT_READ_DR8:     case SVM_EXIT_READ_DR9:
    4774                 case SVM_EXIT_READ_DR10:    case SVM_EXIT_READ_DR11:    case SVM_EXIT_READ_DR12:    case SVM_EXIT_READ_DR13:
    4775                 case SVM_EXIT_READ_DR14:    case SVM_EXIT_READ_DR15:
    4776                     return hmR0SvmExitReadDRx(pVCpu, pCtx, pSvmTransient);
    4777 
    4778                 case SVM_EXIT_WRITE_DR0:    case SVM_EXIT_WRITE_DR1:    case SVM_EXIT_WRITE_DR2:    case SVM_EXIT_WRITE_DR3:
    4779                 case SVM_EXIT_WRITE_DR6:    case SVM_EXIT_WRITE_DR7:    case SVM_EXIT_WRITE_DR8:    case SVM_EXIT_WRITE_DR9:
    4780                 case SVM_EXIT_WRITE_DR10:   case SVM_EXIT_WRITE_DR11:   case SVM_EXIT_WRITE_DR12:   case SVM_EXIT_WRITE_DR13:
    4781                 case SVM_EXIT_WRITE_DR14:   case SVM_EXIT_WRITE_DR15:
    4782                     return hmR0SvmExitWriteDRx(pVCpu, pCtx, pSvmTransient);
    4783 
    4784                 case SVM_EXIT_XSETBV:
    4785                     return hmR0SvmExitXsetbv(pVCpu, pCtx, pSvmTransient);
    4786 
    4787                 case SVM_EXIT_TASK_SWITCH:
    4788                     return hmR0SvmExitTaskSwitch(pVCpu, pCtx, pSvmTransient);
    4789 
    4790                 case SVM_EXIT_IRET:
    4791                     return hmR0SvmExitIret(pVCpu, pCtx, pSvmTransient);
    4792 
    4793                 case SVM_EXIT_SHUTDOWN:
    4794                     return hmR0SvmExitShutdown(pVCpu, pCtx, pSvmTransient);
    4795 
    4796                 case SVM_EXIT_SMI:
    4797                 case SVM_EXIT_INIT:
    4798                 {
    4799                     /*
    4800                      * We don't intercept NMIs. As for INIT signals, it really shouldn't ever happen here. If it ever does,
    4801                      * we want to know about it so log the exit code and bail.
    4802                      */
    4803                     AssertMsgFailed(("hmR0SvmHandleExit: Unexpected exit %#RX32\n", (uint32_t)pSvmTransient->u64ExitCode));
    4804                     pVCpu->hm.s.u32HMError = (uint32_t)pSvmTransient->u64ExitCode;
    4805                     return VERR_SVM_UNEXPECTED_EXIT;
    4806                 }
    4807 
    4808 #ifdef VBOX_WITH_NESTED_HWVIRT
    4809                 case SVM_EXIT_CLGI:     return hmR0SvmExitClgi(pVCpu, pCtx, pSvmTransient);
    4810                 case SVM_EXIT_STGI:     return hmR0SvmExitStgi(pVCpu, pCtx, pSvmTransient);
    4811                 case SVM_EXIT_VMLOAD:   return hmR0SvmExitVmload(pVCpu, pCtx, pSvmTransient);
    4812                 case SVM_EXIT_VMSAVE:   return hmR0SvmExitVmsave(pVCpu, pCtx, pSvmTransient);
    4813                 case SVM_EXIT_INVLPGA:  return hmR0SvmExitInvlpga(pVCpu, pCtx, pSvmTransient);
    4814                 case SVM_EXIT_VMRUN:    return hmR0SvmExitVmrun(pVCpu, pCtx, pSvmTransient);
    4815 #else
    4816                 case SVM_EXIT_CLGI:
    4817                 case SVM_EXIT_STGI:
    4818                 case SVM_EXIT_VMLOAD:
    4819                 case SVM_EXIT_VMSAVE:
    4820                 case SVM_EXIT_INVLPGA:
    4821                 case SVM_EXIT_VMRUN:
    4822 #endif
    4823                 case SVM_EXIT_RSM:
    4824                 case SVM_EXIT_SKINIT:
    4825                     return hmR0SvmExitSetPendingXcptUD(pVCpu, pCtx, pSvmTransient);
    4826 
    4827 #ifdef HMSVM_ALWAYS_TRAP_ALL_XCPTS
    4828                 case SVM_EXIT_EXCEPTION_0:             /* X86_XCPT_DE */
    4829                 /*   SVM_EXIT_EXCEPTION_1: */          /* X86_XCPT_DB - Handled above. */
    4830                 case SVM_EXIT_EXCEPTION_2:             /* X86_XCPT_NMI */
    4831                 /*   SVM_EXIT_EXCEPTION_3: */          /* X86_XCPT_BP - Handled above. */
    4832                 case SVM_EXIT_EXCEPTION_4:             /* X86_XCPT_OF */
    4833                 case SVM_EXIT_EXCEPTION_5:             /* X86_XCPT_BR */
    4834                 /*   SVM_EXIT_EXCEPTION_6: */          /* X86_XCPT_UD - Handled above. */
    4835                 /*   SVM_EXIT_EXCEPTION_7: */          /* X86_XCPT_NM - Handled above. */
    4836                 case SVM_EXIT_EXCEPTION_8:             /* X86_XCPT_DF */
    4837                 case SVM_EXIT_EXCEPTION_9:             /* X86_XCPT_CO_SEG_OVERRUN */
    4838                 case SVM_EXIT_EXCEPTION_10:            /* X86_XCPT_TS */
    4839                 case SVM_EXIT_EXCEPTION_11:            /* X86_XCPT_NP */
    4840                 case SVM_EXIT_EXCEPTION_12:            /* X86_XCPT_SS */
    4841                 case SVM_EXIT_EXCEPTION_13:            /* X86_XCPT_GP */
    4842                 /*   SVM_EXIT_EXCEPTION_14: */         /* X86_XCPT_PF - Handled above. */
    4843                 case SVM_EXIT_EXCEPTION_15:            /* Reserved. */
    4844                 /*   SVM_EXIT_EXCEPTION_16: */         /* X86_XCPT_MF - Handled above. */
    4845                 /*   SVM_EXIT_EXCEPTION_17: */         /* X86_XCPT_AC - Handled above. */
    4846                 case SVM_EXIT_EXCEPTION_18:            /* X86_XCPT_MC */
    4847                 case SVM_EXIT_EXCEPTION_19:            /* X86_XCPT_XF */
    4848                 case SVM_EXIT_EXCEPTION_20: case SVM_EXIT_EXCEPTION_21: case SVM_EXIT_EXCEPTION_22:
    4849                 case SVM_EXIT_EXCEPTION_23: case SVM_EXIT_EXCEPTION_24: case SVM_EXIT_EXCEPTION_25:
    4850                 case SVM_EXIT_EXCEPTION_26: case SVM_EXIT_EXCEPTION_27: case SVM_EXIT_EXCEPTION_28:
    4851                 case SVM_EXIT_EXCEPTION_29: case SVM_EXIT_EXCEPTION_30: case SVM_EXIT_EXCEPTION_31:
    4852                 {
    4853                     /** @todo r=ramshankar; We should be doing
    4854                      *        HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY here! */
    4855 
    4856                     PSVMVMCB pVmcb   = pVCpu->hm.s.svm.pVmcb;
    4857                     SVMEVENT Event;
    4858                     Event.u          = 0;
    4859                     Event.n.u1Valid  = 1;
    4860                     Event.n.u3Type   = SVM_EVENT_EXCEPTION;
    4861                     Event.n.u8Vector = pSvmTransient->u64ExitCode - SVM_EXIT_EXCEPTION_0;
    4862 
    4863                     switch (Event.n.u8Vector)
    4864                     {
    4865                         case X86_XCPT_DE:
    4866                             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDE);
    4867                             break;
    4868 
    4869                         case X86_XCPT_NP:
    4870                             Event.n.u1ErrorCodeValid    = 1;
    4871                             Event.n.u32ErrorCode        = pVmcb->ctrl.u64ExitInfo1;
    4872                             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNP);
    4873                             break;
    4874 
    4875                         case X86_XCPT_SS:
    4876                             Event.n.u1ErrorCodeValid    = 1;
    4877                             Event.n.u32ErrorCode        = pVmcb->ctrl.u64ExitInfo1;
    4878                             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestSS);
    4879                             break;
    4880 
    4881                         case X86_XCPT_GP:
    4882                             Event.n.u1ErrorCodeValid    = 1;
    4883                             Event.n.u32ErrorCode        = pVmcb->ctrl.u64ExitInfo1;
    4884                             STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestGP);
    4885                             break;
    4886 
    4887                         default:
    48885076                            AssertMsgFailed(("hmR0SvmHandleExit: Unexpected exit caused by exception %#x\n", Event.n.u8Vector));
    48895077                            pVCpu->hm.s.u32HMError = Event.n.u8Vector;
     
    50125200}
    50135201
    5014 
    5015 /**
    5016  * Sets an invalid-opcode (\#UD) exception as pending-for-injection into the VM.
    5017  *
    5018  * @param   pVCpu       The cross context virtual CPU structure.
    5019  */
    5020 DECLINLINE(void) hmR0SvmSetPendingXcptUD(PVMCPU pVCpu)
    5021 {
    5022     SVMEVENT Event;
    5023     Event.u          = 0;
    5024     Event.n.u1Valid  = 1;
    5025     Event.n.u3Type   = SVM_EVENT_EXCEPTION;
    5026     Event.n.u8Vector = X86_XCPT_UD;
    5027     hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
    5028 }
    5029 
    5030 
    5031 /**
    5032  * Sets a debug (\#DB) exception as pending-for-injection into the VM.
    5033  *
    5034  * @param   pVCpu       The cross context virtual CPU structure.
    5035  */
    5036 DECLINLINE(void) hmR0SvmSetPendingXcptDB(PVMCPU pVCpu)
    5037 {
    5038     SVMEVENT Event;
    5039     Event.u          = 0;
    5040     Event.n.u1Valid  = 1;
    5041     Event.n.u3Type   = SVM_EVENT_EXCEPTION;
    5042     Event.n.u8Vector = X86_XCPT_DB;
    5043     hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
    5044 }
    5045 
    5046 
    5047 /**
    5048  * Sets a page fault (\#PF) exception as pending-for-injection into the VM.
    5049  *
    5050  * @param   pVCpu           The cross context virtual CPU structure.
    5051  * @param   pCtx            Pointer to the guest-CPU context.
    5052  * @param   u32ErrCode      The error-code for the page-fault.
    5053  * @param   uFaultAddress   The page fault address (CR2).
    5054  *
    5055  * @remarks This updates the guest CR2 with @a uFaultAddress!
    5056  */
    5057 DECLINLINE(void) hmR0SvmSetPendingXcptPF(PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t u32ErrCode, RTGCUINTPTR uFaultAddress)
    5058 {
    5059     SVMEVENT Event;
    5060     Event.u                  = 0;
    5061     Event.n.u1Valid          = 1;
    5062     Event.n.u3Type           = SVM_EVENT_EXCEPTION;
    5063     Event.n.u8Vector         = X86_XCPT_PF;
    5064     Event.n.u1ErrorCodeValid = 1;
    5065     Event.n.u32ErrorCode     = u32ErrCode;
    5066 
    5067     /* Update CR2 of the guest. */
    5068     if (pCtx->cr2 != uFaultAddress)
    5069     {
    5070         pCtx->cr2 = uFaultAddress;
    5071         HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR2);
    5072     }
    5073 
    5074     hmR0SvmSetPendingEvent(pVCpu, &Event, uFaultAddress);
    5075 }
    5076 
    5077 
    5078 /**
    5079  * Sets a device-not-available (\#NM) exception as pending-for-injection into
    5080  * the VM.
    5081  *
    5082  * @param   pVCpu       The cross context virtual CPU structure.
    5083  */
    5084 DECLINLINE(void) hmR0SvmSetPendingXcptNM(PVMCPU pVCpu)
    5085 {
    5086     SVMEVENT Event;
    5087     Event.u          = 0;
    5088     Event.n.u1Valid  = 1;
    5089     Event.n.u3Type   = SVM_EVENT_EXCEPTION;
    5090     Event.n.u8Vector = X86_XCPT_NM;
    5091     hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
    5092 }
    5093 
    5094 
    5095 /**
    5096  * Sets a math-fault (\#MF) exception as pending-for-injection into the VM.
    5097  *
    5098  * @param   pVCpu       The cross context virtual CPU structure.
    5099  */
    5100 DECLINLINE(void) hmR0SvmSetPendingXcptMF(PVMCPU pVCpu)
    5101 {
    5102     SVMEVENT Event;
    5103     Event.u          = 0;
    5104     Event.n.u1Valid  = 1;
    5105     Event.n.u3Type   = SVM_EVENT_EXCEPTION;
    5106     Event.n.u8Vector = X86_XCPT_MF;
    5107     hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
    5108 }
    5109 
    5110 
    5111 /**
    5112  * Sets a double fault (\#DF) exception as pending-for-injection into the VM.
    5113  *
    5114  * @param   pVCpu       The cross context virtual CPU structure.
    5115  */
    5116 DECLINLINE(void) hmR0SvmSetPendingXcptDF(PVMCPU pVCpu)
    5117 {
    5118     SVMEVENT Event;
    5119     Event.u                  = 0;
    5120     Event.n.u1Valid          = 1;
    5121     Event.n.u3Type           = SVM_EVENT_EXCEPTION;
    5122     Event.n.u8Vector         = X86_XCPT_DF;
    5123     Event.n.u1ErrorCodeValid = 1;
    5124     Event.n.u32ErrorCode     = 0;
    5125     hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);
    5126 }
    51275202
    51285203#ifdef HMSVM_USE_IEM_EVENT_REFLECTION
     
    61606235
    61616236/**
     6237 * \#VMEXIT handler for unexpected exits. Conditional \#VMEXIT.
     6238 */
     6239HMSVM_EXIT_DECL hmR0SvmExitUnexpected(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)
     6240{
     6241    RT_NOREF(pCtx);
     6242    AssertMsgFailed(("hmR0SvmExitUnexpected: ExitCode=%#RX64\n", pSvmTransient->u64ExitCode));
     6243    pVCpu->hm.s.u32HMError = (uint32_t)pSvmTransient->u64ExitCode;
     6244    return VERR_SVM_UNEXPECTED_EXIT;
     6245}
     6246
     6247
     6248/**
    61626249 * \#VMEXIT handler for CRx reads (SVM_EXIT_READ_CR*). Conditional \#VMEXIT.
    61636250 */
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