VirtualBox

Changeset 55129 in vbox for trunk/src/VBox/VMM/VMMR0


Ignore:
Timestamp:
Apr 8, 2015 11:31:47 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
99427
Message:

VMM/GIM: Allow dynamic enabling of #UD traps and per-VCPU hypercalls.

Location:
trunk/src/VBox/VMM/VMMR0
Files:
3 edited

Legend:

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

    r55118 r55129  
    12141214    pVM->hm.s.uMaxAsid                  = g_HvmR0.uMaxAsid;
    12151215
    1216     pVM->hm.s.fGIMTrapXcptUD            = GIMShouldTrapXcptUD(pVM);
    1217 
    12181216    if (!pVM->hm.s.cMaxResumeLoops) /* allow ring-3 overrides */
    12191217    {
     
    12291227    {
    12301228        PVMCPU pVCpu = &pVM->aCpus[i];
    1231         pVCpu->hm.s.idEnteredCpu = NIL_RTCPUID;
    1232         pVCpu->hm.s.idLastCpu    = NIL_RTCPUID;
     1229        pVCpu->hm.s.idEnteredCpu   = NIL_RTCPUID;
     1230        pVCpu->hm.s.idLastCpu      = NIL_RTCPUID;
     1231        pVCpu->hm.s.fGIMTrapXcptUD = GIMShouldTrapXcptUD(pVCpu);
    12331232
    12341233        /* We'll aways increment this the first time (host uses ASID 0). */
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r55118 r55129  
    670670    Assert(pVM->hm.s.svm.fSupported);
    671671
    672     uint32_t const fGimXcptIntercepts = pVM->hm.s.fGIMTrapXcptUD ? RT_BIT(X86_XCPT_UD) : 0;
    673672    for (VMCPUID i = 0; i < pVM->cCpus; i++)
    674673    {
     
    787786
    788787        /* Apply the exceptions intercepts needed by the GIM provider. */
    789         pVmcb->ctrl.u32InterceptException |= fGimXcptIntercepts;
     788        if (pVCpu->hm.s.fGIMTrapXcptUD)
     789            pVmcb->ctrl.u32InterceptException |= RT_BIT(X86_XCPT_UD);
    790790
    791791        /*
     
    16341634
    16351635/**
     1636 * Loads the exception interrupts required for guest execution in the VMCB.
     1637 *
     1638 * @returns VBox status code.
     1639 * @param   pVCpu       Pointer to the VMCPU.
     1640 * @param   pVmcb       Pointer to the VM control block.
     1641 * @param   pCtx        Pointer to the guest-CPU context.
     1642 */
     1643static int hmR0SvmLoadGuestXcptIntercepts(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX pCtx)
     1644{
     1645    int rc = VINF_SUCCESS;
     1646    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
     1647    {
     1648        if (pVCpu->hm.s.fGIMTrapXcptUD)
     1649            hmR0SvmAddXcptIntercept(pVmcb, X86_XCPT_UD);
     1650        else
     1651            hmR0SvmRemoveXcptIntercept(pVmcb, X86_XCPT_UD);
     1652        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
     1653    }
     1654    return rc;
     1655}
     1656
     1657
     1658/**
    16361659 * Sets up the appropriate function to run guest code.
    16371660 *
     
    18161839    rc = hmR0SvmLoadGuestApicState(pVCpu, pVmcb, pCtx);
    18171840    AssertLogRelMsgRCReturn(rc, ("hmR0SvmLoadGuestApicState! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
     1841
     1842    rc = hmR0SvmLoadGuestXcptIntercepts(pVCpu, pVmcb, pCtx);
     1843    AssertLogRelMsgRCReturn(rc, ("hmR0SvmLoadGuestXcptIntercepts! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
    18181844
    18191845    rc = hmR0SvmSetupVMRunHandler(pVCpu, pCtx);
     
    50085034    else if (rc == VERR_NOT_FOUND)
    50095035    {
    5010         PVM pVM = pVCpu->CTX_SUFF(pVM);
    5011         if (pVM->hm.s.fHypercallsEnabled)
     5036        if (pVCpu->hm.s.fHypercallsEnabled)
    50125037        {
    50135038            rc = GIMHypercall(pVCpu, pCtx);
     
    52275252    HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY();
    52285253
    5229     PVM pVM = pVCpu->CTX_SUFF(pVM);
    5230     if (pVM->hm.s.fGIMTrapXcptUD)
     5254    if (pVCpu->hm.s.fGIMTrapXcptUD)
    52315255        GIMXcptUD(pVCpu, pCtx, NULL /* pDis */);
    52325256    else
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r55118 r55129  
    26352635    LogFlowFunc(("pVM=%p pVCpu=%p\n", pVM, pVCpu));
    26362636
    2637     uint32_t u32XcptBitmap = 0;
     2637    uint32_t u32XcptBitmap = pVCpu->hm.s.fGIMTrapXcptUD ? RT_BIT(X86_XCPT_UD) : 0;
    26382638
    26392639    /* Without Nested Paging, #PF must cause a VM-exit so we can sync our shadow page tables. */
     
    35543554
    35553555/**
     3556 * Loads the exception intercepts required for guest execution in the VMCS.
     3557 *
     3558 * @returns VBox status code.
     3559 * @param   pVCpu       Pointer to the VMCPU.
     3560 * @param   pMixedCtx   Pointer to the guest-CPU context. The data may be
     3561 *                      out-of-sync. Make sure to update the required fields
     3562 *                      before using them.
     3563 */
     3564static int hmR0VmxLoadGuestXcptIntercepts(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     3565{
     3566    NOREF(pMixedCtx);
     3567    int rc = VINF_SUCCESS;
     3568    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
     3569    {
     3570        /* The remaining exception intercepts are handled elsewhere, e.g. in hmR0VmxLoadSharedCR0(). */
     3571        if (pVCpu->hm.s.fGIMTrapXcptUD)
     3572            pVCpu->hm.s.vmx.u32XcptBitmap |= RT_BIT(X86_XCPT_UD);
     3573        else
     3574        {
     3575#ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
     3576            pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_UD);
     3577#endif
     3578        }
     3579
     3580        rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
     3581        AssertRCReturn(rc, rc);
     3582
     3583        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
     3584        Log4(("Load[%RU32]: VMX_VMCS32_CTRL_EXCEPTION_BITMAP=%#RX64 fContextUseFlags=%#RX32\n", pVCpu->idCpu,
     3585              pVCpu->hm.s.vmx.u32XcptBitmap, HMCPU_CF_VALUE(pVCpu)));
     3586    }
     3587    return rc;
     3588}
     3589
     3590
     3591/**
    35563592 * Loads the guest's RIP into the guest-state area in the VMCS.
    35573593 *
     
    37793815            pVCpu->hm.s.vmx.u32XcptBitmap &= ~HMVMX_REAL_MODE_XCPT_MASK;
    37803816        }
     3817        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
    37813818
    37823819        if (fInterceptNM)
     
    38233860        u32GuestCR0 &= ~(X86_CR0_CD | X86_CR0_NW);          /* Always enable caching. */
    38243861
    3825         /* Write VT-x's view of the guest CR0 into the VMCS and update the exception bitmap. */
     3862        /* Write VT-x's view of the guest CR0 into the VMCS. */
    38263863        rc = VMXWriteVmcs32(VMX_VMCS_GUEST_CR0, u32GuestCR0);
    3827         AssertRCReturn(rc, rc);
    3828         rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
    38293864        AssertRCReturn(rc, rc);
    38303865        Log4(("Load[%RU32]: VMX_VMCS_GUEST_CR0=%#RX32 (uSetCR0=%#RX32 uZapCR0=%#RX32)\n", pVCpu->idCpu, u32GuestCR0, uSetCR0,
     
    42204255    if (   fInterceptDB
    42214256        || pVCpu->hm.s.vmx.RealMode.fRealOnV86Active)
     4257    {
    42224258        pVCpu->hm.s.vmx.u32XcptBitmap |= RT_BIT(X86_XCPT_DB);
     4259        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
     4260    }
    42234261    else
    42244262    {
    42254263#ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
    42264264        pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_DB);
    4227 #endif
    4228     }
    4229     rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
    4230     AssertRCReturn(rc, rc);
     4265        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
     4266#endif
     4267    }
    42314268
    42324269    /*
     
    82958332    AssertLogRelMsgRCReturn(rc, ("hmR0VmxLoadGuestApicState! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
    82968333
     8334    rc = hmR0VmxLoadGuestXcptIntercepts(pVCpu, pMixedCtx);
     8335    AssertLogRelMsgRCReturn(rc, ("hmR0VmxLoadGuestXcptIntercepts! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
     8336
    82978337    /*
    82988338     * Loading Rflags here is fine, even though Rflags.TF might depend on guest debug state (which is not loaded here).
     
    83548394#endif
    83558395        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_LAZY_MSRS);
     8396    }
     8397
     8398    /* Loading CR0, debug state might have changed intercepts, update VMCS. */
     8399    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
     8400    {
     8401        int rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
     8402        AssertRC(rc);
     8403        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
    83568404    }
    83578405
     
    1024310291    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitVmcall);
    1024410292
    10245     PVM pVM = pVCpu->CTX_SUFF(pVM);
    10246     if (pVM->hm.s.fHypercallsEnabled)
     10293    if (pVCpu->hm.s.fHypercallsEnabled)
    1024710294    {
    1024810295#if 0
     
    1140511452#ifndef HMVMX_ALWAYS_TRAP_ALL_XCPTS
    1140611453            pVCpu->hm.s.vmx.u32XcptBitmap &= ~RT_BIT(X86_XCPT_DB);
    11407             rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
    11408             AssertRCReturn(rc, rc);
     11454            HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
    1140911455#endif
    1141011456        }
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