VirtualBox

Changeset 71312 in vbox for trunk


Ignore:
Timestamp:
Mar 13, 2018 10:55:27 AM (7 years ago)
Author:
vboxsync
Message:

VMM/HMSVMR0: Nested Hw.virt: Explicitly skip intercepting #UD and #BP while executing the nested-guest just because the outer guest might happen to intercept them for purposes that are currently irrelevant
for the nested-guest.

File:
1 edited

Legend:

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

    r71188 r71312  
    14221422    if (!pVCpu->CTX_SUFF(pVM)->hm.s.fNestedPaging)
    14231423    {
    1424         u64GuestCR0 |= X86_CR0_PG;     /* When Nested Paging is not available, use shadow page tables. */
    1425         u64GuestCR0 |= X86_CR0_WP;     /* Guest CPL 0 writes to its read-only pages should cause a #PF #VMEXIT. */
     1424        u64GuestCR0 |= X86_CR0_PG      /* When Nested Paging is not available, use shadow page tables. */
     1425                    | X86_CR0_WP;     /* Guest CPL 0 writes to its read-only pages should cause a #PF #VMEXIT. */
    14261426    }
    14271427
     
    14441444    {
    14451445        fInterceptNM = true;           /* Guest FPU inactive, #VMEXIT on #NM for lazy FPU loading. */
    1446         u64GuestCR0 |=  X86_CR0_TS     /* Guest can task switch quickly and do lazy FPU syncing. */
    1447                       | X86_CR0_MP;    /* FWAIT/WAIT should not ignore CR0.TS and should generate #NM. */
     1446        u64GuestCR0 |= X86_CR0_TS      /* Guest can task switch quickly and do lazy FPU syncing. */
     1447                    |  X86_CR0_MP;     /* FWAIT/WAIT should not ignore CR0.TS and should generate #NM. */
    14481448    }
    14491449
     
    19431943static void hmR0SvmLoadGuestXcptIntercepts(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX pCtx)
    19441944{
     1945    /* If we modify intercepts from here, please check & adjust hmR0SvmLoadGuestXcptInterceptsNested()
     1946       if required. */
    19451947    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
    19461948    {
     
    19791981    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
    19801982    {
    1981         /* First, load the guest exception intercepts into the guest VMCB. */
    19821983        PSVMVMCB pVmcb = pVCpu->hm.s.svm.pVmcb;
    1983         hmR0SvmLoadGuestXcptIntercepts(pVCpu, pVmcb, pCtx);
    1984 
    1985         /* Next, merge the intercepts into the nested-guest VMCB. */
     1984
     1985        /* Merge the guest's CR intercepts into the nested-guest VMCB. */
    19861986        pVmcbNstGst->ctrl.u16InterceptRdCRx |= pVmcb->ctrl.u16InterceptRdCRx;
    19871987        pVmcbNstGst->ctrl.u16InterceptWrCRx |= pVmcb->ctrl.u16InterceptWrCRx;
     
    19911991        pVmcbNstGst->ctrl.u16InterceptWrCRx |= RT_BIT(0) | RT_BIT(4);
    19921992
    1993         /* Always intercept CR3 reads and writes without nested-paging as we load shadow page tables. */
     1993        /* Without nested paging, intercept CR3 reads and writes as we load shadow page tables. */
    19941994        if (!pVCpu->CTX_SUFF(pVM)->hm.s.fNestedPaging)
    19951995        {
     
    20022002        pVmcbNstGst->ctrl.u16InterceptRdDRx |= 0xffff;
    20032003        pVmcbNstGst->ctrl.u16InterceptWrDRx |= 0xffff;
     2004
     2005        /*
     2006         * Merge the guest's exception intercepts into the nested-guest VMCB.
     2007         *
     2008         * - \#UD: Exclude these as the outer guest's GIM hypercalls are not applicable
     2009         * while executing the nested-guest.
     2010         *
     2011         * - \#BP: Exclude breakpoints set by the VM debugger for the outer guest. This can
     2012         * be tweaked later depending on how we wish to implement breakpoints.
     2013         *
     2014         * Warning!! This ASSUMES we only intercept \#UD for hypercall purposes and \#BP
     2015         * for VM debugger breakpoints, see hmR0SvmLoadGuestXcptIntercepts.
     2016         */
     2017#ifndef HMSVM_ALWAYS_TRAP_ALL_XCPTS
     2018        pVmcbNstGst->ctrl.u32InterceptXcpt  |= (pVmcb->ctrl.u32InterceptXcpt & ~(  RT_BIT(X86_XCPT_UD)
     2019                                                                                 | RT_BIT(X86_XCPT_BP)));
     2020#else
     2021        pVmcbNstGst->ctrl.u32InterceptXcpt  |= pVmcb->ctrl.u32InterceptXcpt;
     2022#endif
    20042023
    20052024        /*
     
    20132032         *   the nested-guest, the physical CPU raises a \#UD exception as expected.
    20142033         */
    2015         pVmcbNstGst->ctrl.u32InterceptXcpt  |= pVmcb->ctrl.u32InterceptXcpt;
    2016         pVmcbNstGst->ctrl.u64InterceptCtrl  |= (pVmcb->ctrl.u64InterceptCtrl & (  ~SVM_CTRL_INTERCEPT_VINTR
    2017                                                                                 | ~SVM_CTRL_INTERCEPT_VMMCALL))
     2034        pVmcbNstGst->ctrl.u64InterceptCtrl  |= (pVmcb->ctrl.u64InterceptCtrl & ~(  SVM_CTRL_INTERCEPT_VINTR
     2035                                                                                 | SVM_CTRL_INTERCEPT_VMMCALL))
    20182036                                            |  HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS;
    20192037
     
    20432061        /* Finally, update the VMCB clean bits. */
    20442062        pVmcbNstGst->ctrl.u32VmcbCleanBits  &= ~HMSVM_VMCB_CLEAN_INTERCEPTS;
    2045 
    2046         Assert(!HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS));
     2063        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
    20472064    }
    20482065}
     
    29222939        && !(pVmcbNstGstCache->u64InterceptCtrl & (SVM_CTRL_INTERCEPT_RDTSC | SVM_CTRL_INTERCEPT_RDTSCP)))
    29232940    {
    2924         pVmcbNstGstCtrl->u64InterceptCtrl &= ~SVM_CTRL_INTERCEPT_RDTSC;
    2925         pVmcbNstGstCtrl->u64InterceptCtrl &= ~SVM_CTRL_INTERCEPT_RDTSCP;
     2941        pVmcbNstGstCtrl->u64InterceptCtrl &= ~(SVM_CTRL_INTERCEPT_RDTSC | SVM_CTRL_INTERCEPT_RDTSCP);
    29262942        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscOffset);
    29272943    }
    29282944    else
    29292945    {
    2930         pVmcbNstGstCtrl->u64InterceptCtrl |= SVM_CTRL_INTERCEPT_RDTSC;
    2931         pVmcbNstGstCtrl->u64InterceptCtrl |= SVM_CTRL_INTERCEPT_RDTSCP;
     2946        pVmcbNstGstCtrl->u64InterceptCtrl |= SVM_CTRL_INTERCEPT_RDTSC | SVM_CTRL_INTERCEPT_RDTSCP;
    29322947        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscIntercept);
    29332948    }
     
    29682983    if (fCanUseRealTsc)
    29692984    {
    2970         pVmcb->ctrl.u64InterceptCtrl &= ~SVM_CTRL_INTERCEPT_RDTSC;
    2971         pVmcb->ctrl.u64InterceptCtrl &= ~SVM_CTRL_INTERCEPT_RDTSCP;
     2985        pVmcb->ctrl.u64InterceptCtrl &= ~(SVM_CTRL_INTERCEPT_RDTSC | SVM_CTRL_INTERCEPT_RDTSCP);
    29722986        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscOffset);
    29732987    }
    29742988    else
    29752989    {
    2976         pVmcb->ctrl.u64InterceptCtrl |= SVM_CTRL_INTERCEPT_RDTSC;
    2977         pVmcb->ctrl.u64InterceptCtrl |= SVM_CTRL_INTERCEPT_RDTSCP;
     2990        pVmcb->ctrl.u64InterceptCtrl |= SVM_CTRL_INTERCEPT_RDTSC | SVM_CTRL_INTERCEPT_RDTSCP;
    29782991        STAM_COUNTER_INC(&pVCpu->hm.s.StatTscIntercept);
    29792992    }
     
    53735386                }
    53745387
     5388                /** @todo Needed when restoring saved-state when saved state support wasn't yet
     5389                 *        added. Perhaps it won't be required later. */
     5390#if 0
     5391                case SVM_EXIT_NPF:
     5392                {
     5393                    Assert(pVCpu->CTX_SUFF(pVM)->hm.s.fNestedPaging);
     5394                    if (HMIsGuestSvmXcptInterceptSet(pVCpu, pCtx, X86_XCPT_PF))
     5395                        return HM_SVM_VMEXIT_NESTED(pVCpu, SVM_EXIT_EXCEPTION_14, RT_LO_U32(uExitInfo1), uExitInfo2);
     5396                    hmR0SvmSetPendingXcptPF(pVCpu, pCtx, RT_LO_U32(uExitInfo1), uExitInfo2);
     5397                    return VINF_SUCCESS;
     5398                }
     5399#else
     5400                case SVM_EXIT_NPF:
     5401#endif
    53755402                case SVM_EXIT_INIT:  /* We shouldn't get INIT signals while executing a nested-guest. */
    5376                 case SVM_EXIT_NPF:   /* We don't yet support nested-paging for nested-guests, so this should never happen. */
    53775403                {
    53785404                    return hmR0SvmExitUnexpected(pVCpu, pCtx, pSvmTransient);
     
    64236449{
    64246450    RT_NOREF(pCtx);
    6425     AssertMsgFailed(("hmR0SvmExitUnexpected: ExitCode=%#RX64\n", pSvmTransient->u64ExitCode));
     6451    PCSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu, pCtx);
     6452    AssertMsgFailed(("hmR0SvmExitUnexpected: ExitCode=%#RX64 uExitInfo1=%#RX64 uExitInfo2=%#RX64\n", pSvmTransient->u64ExitCode,
     6453                     pVmcb->ctrl.u64ExitInfo1, pVmcb->ctrl.u64ExitInfo2));
     6454    RT_NOREF(pVmcb);
    64266455    pVCpu->hm.s.u32HMError = (uint32_t)pSvmTransient->u64ExitCode;
    64276456    return VERR_SVM_UNEXPECTED_EXIT;
     
    70007029    /* See AMD spec. 15.25.6 "Nested versus Guest Page Faults, Fault Ordering" for VMCB details for #NPF. */
    70017030    PSVMVMCB pVmcb           = pVCpu->hm.s.svm.pVmcb;
    7002     uint32_t u32ErrCode      = pVmcb->ctrl.u64ExitInfo1;
     7031    uint32_t u32ErrCode      = pVmcb->ctrl.u64ExitInfo1;    /** @todo Make it more explicit that high bits can be non-zero. */
    70037032    RTGCPHYS GCPhysFaultAddr = pVmcb->ctrl.u64ExitInfo2;
    70047033
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