VirtualBox

Changeset 65222 in vbox


Ignore:
Timestamp:
Jan 10, 2017 12:33:45 PM (8 years ago)
Author:
vboxsync
Message:

VMM/HMVMXR0: Fix longjump when mapping the APIC access page, map the page just once.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

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

    r65137 r65222  
    34033403 *                      out-of-sync. Make sure to update the required fields
    34043404 *                      before using them.
     3405 *
     3406 * @remarks Can cause longjumps!!!
    34053407 */
    34063408DECLINLINE(int) hmR0VmxLoadGuestApicState(PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     
    34143416            && APICIsEnabled(pVCpu))
    34153417        {
     3418            /*
     3419             * Setup TPR shadowing.
     3420             */
    34163421            if (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW)
    34173422            {
     
    34453450
    34463451#ifndef IEM_VERIFICATION_MODE_FULL
    3447             /* Setup the Virtualized APIC accesses. */
     3452            /*
     3453             * Setup the virtualized-APIC accesses.
     3454             *
     3455             * Note! This can cause a longjumps to R3 due to the acquisition of the PGM lock
     3456             * in both PGMHandlerPhysicalReset() and IOMMMIOMapMMIOHCPage(), see @bugref{8721}.
     3457             */
    34483458            if (pVCpu->hm.s.vmx.u32ProcCtls2 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
    34493459            {
     
    34513461                if (u64MsrApicBase != pVCpu->hm.s.vmx.u64MsrApicBase)
    34523462                {
     3463                    /* We only care about the APIC base MSR address and not the other bits. */
    34533464                    PVM pVM = pVCpu->CTX_SUFF(pVM);
    34543465                    Assert(pVM->hm.s.vmx.HCPhysApicAccess);
     
    34573468                    GCPhysApicBase &= PAGE_BASE_GC_MASK;
    34583469
    3459                     /* Unalias any existing mapping. */
    3460                     rc = PGMHandlerPhysicalReset(pVM, GCPhysApicBase);
    3461                     AssertRCReturn(rc, rc);
    3462 
    3463                     /* Map the HC APIC-access page into the GC space, this also updates the shadow page tables if necessary. */
    3464                     Log4(("Mapped HC APIC-access page into GC: GCPhysApicBase=%#RGp\n", GCPhysApicBase));
    3465                     rc = IOMMMIOMapMMIOHCPage(pVM, pVCpu, GCPhysApicBase, pVM->hm.s.vmx.HCPhysApicAccess, X86_PTE_RW | X86_PTE_P);
    3466                     AssertRCReturn(rc, rc);
    3467 
    3468                     /* Update VMX's cache of the APIC base. */
     3470                    /*
     3471                     * We only need a single HC page as the APIC-access page for all VCPUs as it's used
     3472                     * purely for causing VM-exits and not for data access within the actual page.
     3473                     *
     3474                     * The following check ensures we do the mapping on a per-VM basis as our APIC code
     3475                     * does not allow different APICs to be mapped at different addresses on different VCPUs.
     3476                     *
     3477                     * In fact, we do not support remapping of the APIC base at all, see APICSetBaseMsr()
     3478                     * so we just map this once per-VM.
     3479                     */
     3480                    if (ASMAtomicCmpXchgU64(&pVM->hm.s.vmx.GCPhysApicBase, GCPhysApicBase, 0 /* u64Old */))
     3481                    {
     3482                        /* Unalias any existing mapping. */
     3483                        rc = PGMHandlerPhysicalReset(pVM, GCPhysApicBase);
     3484                        AssertRCReturn(rc, rc);
     3485
     3486                        /* Map the HC APIC-access page in place of the MMIO page, also updates the shadow page tables if necessary. */
     3487                        Log4(("HM: VCPU%u: Mapped HC APIC-access page GCPhysApicBase=%#RGp\n", pVCpu->idCpu, GCPhysApicBase));
     3488                        rc = IOMMMIOMapMMIOHCPage(pVM, pVCpu, GCPhysApicBase, pVM->hm.s.vmx.HCPhysApicAccess, X86_PTE_RW | X86_PTE_P);
     3489                        AssertRCReturn(rc, rc);
     3490                    }
     3491
     3492                    /* Update the per-VCPU cache of the APIC base MSR. */
    34693493                    pVCpu->hm.s.vmx.u64MsrApicBase = u64MsrApicBase;
    34703494                }
     
    83868410 *                      out-of-sync. Make sure to update the required fields
    83878411 *                      before using them.
    8388  *
    8389  * @remarks No-long-jump zone!!!  (Disables and enables long jmps for itself,
    8390  *          caller disables then again on successfull return.  Confusing.)
    83918412 */
    83928413static VBOXSTRICTRC hmR0VmxLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx)
     
    83968417    AssertPtr(pMixedCtx);
    83978418    HMVMX_ASSERT_PREEMPT_SAFE();
    8398 
    8399     VMMRZCallRing3Disable(pVCpu);
    8400     Assert(VMMR0IsLogFlushDisabled(pVCpu));
    84018419
    84028420    LogFlowFunc(("pVM=%p pVCpu=%p\n", pVM, pVCpu));
     
    84658483    /* Clear any unused and reserved bits. */
    84668484    HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_CR2);
    8467 
    8468     VMMRZCallRing3Enable(pVCpu);
    84698485
    84708486    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatLoadGuestState, x);
  • trunk/src/VBox/VMM/include/HMInternal.h

    r65137 r65222  
    461461        /** Virtual address of the identity page table used for real mode and protected mode without paging emulation in EPT mode. */
    462462        R3PTRTYPE(PX86PD)           pNonPagingModeEPTPageTable;
     463
     464        /** The guest's MSR APIC base address at which the APIC access page is mapped. */
     465        RTGCPHYS volatile           GCPhysApicBase;
    463466
    464467        /** Physical address of the APIC-access page. */
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