VirtualBox

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


Ignore:
Timestamp:
Sep 12, 2012 11:13:58 AM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
80728
Message:

VMM: Attempt at unbreaking the SUPR0EnableVTx code.

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

Legend:

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

    r43303 r43307  
    9191    DECLR0CALLBACKMEMBER(int, pfnLoadGuestState,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
    9292    DECLR0CALLBACKMEMBER(int, pfnRunGuestCode,(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx));
    93     DECLR0CALLBACKMEMBER(int, pfnEnableCpu,(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage));
     93    DECLR0CALLBACKMEMBER(int, pfnEnableCpu,(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage,
     94                                            bool fEnabledByHost));
    9495    DECLR0CALLBACKMEMBER(int, pfnDisableCpu,(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage));
    9596    DECLR0CALLBACKMEMBER(int, pfnInitVM,(PVM pVM));
     
    251252}
    252253
    253 static DECLCALLBACK(int) hmR0DummyEnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
    254 {
    255     NOREF(pCpu); NOREF(pVM); NOREF(pvCpuPage); NOREF(HCPhysCpuPage);
     254static DECLCALLBACK(int) hmR0DummyEnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage,
     255                                            bool fEnabledBySystem)
     256{
     257    NOREF(pCpu); NOREF(pVM); NOREF(pvCpuPage); NOREF(HCPhysCpuPage); NOREF(fEnabledBySystem);
    256258    return VINF_SUCCESS;
    257259}
     
    467469                        g_HvmR0.vmx.fSupported = true;
    468470                        VMXDisable();
    469 
    470                         /*
    471                          * Check for the VMX-Preemption Timer and adjust for the * "VMX-Preemption
    472                          * Timer Does Not Count Down at the Rate Specified" erratum.
    473                          */
    474                         if (  g_HvmR0.vmx.msr.vmx_pin_ctls.n.allowed1
    475                             & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
    476                         {
    477                             g_HvmR0.vmx.fUsePreemptTimer   = true;
    478                             g_HvmR0.vmx.cPreemptTimerShift = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(g_HvmR0.vmx.msr.vmx_misc);
    479                             if (hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum())
    480                                 g_HvmR0.vmx.cPreemptTimerShift = 0; /* This is about right most of the time here. */
    481                         }
    482471                    }
    483472                    else
     
    512501            }
    513502
    514             /*
    515              * Install the VT-x methods.
    516              */
    517503            if (g_HvmR0.vmx.fSupported)
    518504            {
     505                /*
     506                 * Install the VT-x methods.
     507                 */
    519508                g_HvmR0.pfnEnterSession     = VMXR0Enter;
    520509                g_HvmR0.pfnLeaveSession     = VMXR0Leave;
     
    527516                g_HvmR0.pfnTermVM           = VMXR0TermVM;
    528517                g_HvmR0.pfnSetupVM          = VMXR0SetupVM;
     518
     519                /*
     520                 * Check for the VMX-Preemption Timer and adjust for the * "VMX-Preemption
     521                 * Timer Does Not Count Down at the Rate Specified" erratum.
     522                 */
     523                if (  g_HvmR0.vmx.msr.vmx_pin_ctls.n.allowed1
     524                    & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
     525                {
     526                    g_HvmR0.vmx.fUsePreemptTimer   = true;
     527                    g_HvmR0.vmx.cPreemptTimerShift = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(g_HvmR0.vmx.msr.vmx_misc);
     528                    if (hmR0InitIntelIsSubjectToVmxPreemptionTimerErratum())
     529                        g_HvmR0.vmx.cPreemptTimerShift = 0; /* This is about right most of the time here. */
     530                }
    529531            }
    530532        }
     
    864866    PHMGLOBLCPUINFO pCpu = &g_HvmR0.aCpuInfo[idCpu];
    865867
    866     Assert(!g_HvmR0.vmx.fSupported || !g_HvmR0.vmx.fUsingSUPR0EnableVTx);
    867868    Assert(idCpu == (RTCPUID)RTMpCpuIdToSetIndex(idCpu)); /// @todo fix idCpu == index assumption (rainy day)
    868869    Assert(idCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo));
     
    874875    /* Do NOT reset cTLBFlushes here, see @bugref{6255}. */
    875876
    876     /* Should never happen */
    877     AssertLogRelMsgReturn(pCpu->hMemObj != NIL_RTR0MEMOBJ, ("hmR0EnableCpu failed idCpu=%u.\n", idCpu), VERR_HM_IPE_1);
    878 
    879     void    *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
    880     RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
    881 
    882     int rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage);
     877    int rc;
     878    if (g_HvmR0.vmx.fSupported && g_HvmR0.vmx.fUsingSUPR0EnableVTx)
     879        rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, NULL, NIL_RTHCPHYS, true);
     880    else
     881    {
     882        AssertLogRelMsgReturn(pCpu->hMemObj != NIL_RTR0MEMOBJ, ("hmR0EnableCpu failed idCpu=%u.\n", idCpu), VERR_HM_IPE_1);
     883        void    *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
     884        RTHCPHYS HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
     885        rc = g_HvmR0.pfnEnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
     886    }
    883887    AssertRC(rc);
    884888    if (RT_SUCCESS(rc))
     
    932936    g_HvmR0.fGlobalInit = pVM->hwaccm.s.fGlobalInit;
    933937
     938    for (unsigned i = 0; i < RT_ELEMENTS(g_HvmR0.aCpuInfo); i++)
     939    {
     940        Assert(g_HvmR0.aCpuInfo[i].hMemObj == NIL_RTR0MEMOBJ);
     941        g_HvmR0.aCpuInfo[i].fConfigured = false;
     942        g_HvmR0.aCpuInfo[i].cTLBFlushes = 0;
     943    }
     944
    934945    int rc;
    935946    if (   g_HvmR0.vmx.fSupported
     
    941952        rc = SUPR0EnableVTx(true /* fEnable */);
    942953        if (RT_SUCCESS(rc))
    943         {
    944             for (unsigned iCpu = 0; iCpu < RT_ELEMENTS(g_HvmR0.aCpuInfo); iCpu++)
    945             {
    946                 g_HvmR0.aCpuInfo[iCpu].fConfigured = true;
    947                 g_HvmR0.aCpuInfo[iCpu].cTLBFlushes = 0;
    948                 Assert(g_HvmR0.aCpuInfo[iCpu].hMemObj == NIL_RTR0MEMOBJ);
    949             }
    950 
    951954            /* If the host provides a VT-x init API, then we'll rely on that for global init. */
    952955            g_HvmR0.fGlobalInit = pVM->hwaccm.s.fGlobalInit = true;
    953         }
    954956        else
    955957            AssertMsgFailed(("hmR0EnableAllCpuOnce/SUPR0EnableVTx: rc=%Rrc\n", rc));
     
    973975                ASMMemZeroPage(pvR0);
    974976            }
    975             g_HvmR0.aCpuInfo[i].fConfigured = false;
    976             g_HvmR0.aCpuInfo[i].cTLBFlushes = 0;
    977977        }
    978978
    979         if (g_HvmR0.fGlobalInit)
    980         {
    981             /* First time, so initialize each cpu/core. */
    982             HMR0FIRSTRC FirstRc;
    983             hmR0FirstRcInit(&FirstRc);
    984             rc = RTMpOnAll(hmR0EnableCpuCallback, (void *)pVM, &FirstRc);
    985             if (RT_SUCCESS(rc))
    986                 rc = hmR0FirstRcGetStatus(&FirstRc);
    987             AssertMsgRC(rc, ("hmR0EnableAllCpuOnce failed for cpu %d with rc=%d\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
    988         }
    989         else
    990             rc = VINF_SUCCESS;
     979        rc = VINF_SUCCESS;
     980    }
     981
     982    if (RT_SUCCESS(rc) && g_HvmR0.fGlobalInit)
     983    {
     984        /* First time, so initialize each cpu/core. */
     985        HMR0FIRSTRC FirstRc;
     986        hmR0FirstRcInit(&FirstRc);
     987        rc = RTMpOnAll(hmR0EnableCpuCallback, (void *)pVM, &FirstRc);
     988        if (RT_SUCCESS(rc))
     989            rc = hmR0FirstRcGetStatus(&FirstRc);
     990        AssertMsgRC(rc, ("hmR0EnableAllCpuOnce failed for cpu %d with rc=%d\n", hmR0FirstRcGetCpuId(&FirstRc), rc));
    991991    }
    992992
     
    17541754    void           *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
    17551755    RTHCPHYS        HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
    1756     return VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage);
     1756    return VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
    17571757}
    17581758
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r43073 r43307  
    7676 * @param   HCPhysCpuPage   Physical address of the global CPU page.
    7777 */
    78 VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
     78VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, bool fEnabledByHost)
    7979{
     80    AssertReturn(!fEnabledByHost, VERR_INVALID_PARAMETER);
    8081    AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
    8182    AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.h

    r41906 r43307  
    5858VMMR0DECL(int) SVMR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
    5959
    60 /**
    61  * Sets up and activates AMD-V on the current CPU
    62  *
    63  * @returns VBox status code.
    64  * @param   pCpu            Pointer to the CPU info struct.
    65  * @param   pVM             Pointer to the VM (can be NULL after a resume!).
    66  * @param   pvPageCpu       Pointer to the global CPU page.
    67  * @param   pPageCpuPhys    Physical address of the global CPU page.
    68  */
    69 VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage);
     60VMMR0DECL(int) SVMR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage, bool fEnabledBySystem);
    7061
    7162/**
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r43150 r43307  
    117117 * @param   pvCpuPage       Pointer to the global CPU page.
    118118 * @param   HCPhysCpuPage   Physical address of the global CPU page.
     119 * @param   fEnabledByHost  Set if SUPR0EnableVTx or similar was used to enable
     120 *                          VT-x/AMD-V on the host.
    119121 */
    120 VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
     122VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, bool fEnabledByHost)
    121123{
    122     AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
    123     AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
    124 
    125     if (pVM)
    126     {
    127         /* Set revision dword at the beginning of the VMXON structure. */
    128         *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
    129     }
    130 
    131     /** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption.
    132      * (which can have very bad consequences!!!)
    133      */
    134 
    135     if (ASMGetCR4() & X86_CR4_VMXE)
    136         return VERR_VMX_IN_VMX_ROOT_MODE;
    137 
    138     ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);    /* Make sure the VMX instructions don't cause #UD faults. */
    139 
    140     /*
    141      * Enter VM root mode.
    142      */
    143     int rc = VMXEnable(HCPhysCpuPage);
    144     if (RT_FAILURE(rc))
    145     {
    146         ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
    147         return VERR_VMX_VMXON_FAILED;
     124    if (!fEnabledByHost)
     125    {
     126        AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
     127        AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
     128
     129        if (pVM)
     130        {
     131            /* Set revision dword at the beginning of the VMXON structure. */
     132            *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
     133        }
     134
     135        /** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption.
     136         * (which can have very bad consequences!!!)
     137         */
     138
     139        if (ASMGetCR4() & X86_CR4_VMXE)
     140            return VERR_VMX_IN_VMX_ROOT_MODE;
     141
     142        ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);    /* Make sure the VMX instructions don't cause #UD faults. */
     143
     144        /*
     145         * Enter VM root mode.
     146         */
     147        int rc = VMXEnable(HCPhysCpuPage);
     148        if (RT_FAILURE(rc))
     149        {
     150            ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
     151            return VERR_VMX_VMXON_FAILED;
     152        }
    148153    }
    149154
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.h

    r41906 r43307  
    122122VMMR0DECL(int) VMXR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
    123123
    124 
    125 /**
    126  * Sets up and activates VT-x on the current CPU.
    127  *
    128  * @returns VBox status code.
    129  * @param   pCpu            Pointer to the CPU info struct.
    130  * @param   pVM             Pointer to the VM. (can be NULL after a resume)
    131  * @param   pvPageCpu       Pointer to the global CPU page.
    132  * @param   pPageCpuPhys    Physical address of the global CPU page.
    133  */
    134 VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
     124VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys, bool fEnabledBySystem);
    135125
    136126/**
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