VirtualBox

Changeset 43379 in vbox


Ignore:
Timestamp:
Sep 20, 2012 11:29:12 PM (12 years ago)
Author:
vboxsync
Message:

SUPDrv,VMM: Prepared for SUPR0EnableVTx on darwin.

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/sup.h

    r41147 r43379  
    13631363SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void);
    13641364SUPR0DECL(int) SUPR0EnableVTx(bool fEnable);
     1365SUPR0DECL(bool) SUPR0SuspendVTxOnCpu(void);
     1366SUPR0DECL(void) SUPR0ResumeVTxOnCpu(bool fSuspended);
    13651367
    13661368/** @name Absolute symbols
  • trunk/include/VBox/vmm/hwaccm.h

    r37320 r43379  
    2929#include <VBox/vmm/pgm.h>
    3030#include <VBox/vmm/cpum.h>
     31#include <VBox/vmm/vmm.h>
    3132#include <iprt/mp.h>
    3233
     
    8283VMMR0DECL(int)          HWACCMR0TermVM(PVM pVM);
    8384VMMR0DECL(int)          HWACCMR0EnableAllCpus(PVM pVM);
    84 VMMR0DECL(int)          HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled);
    85 VMMR0DECL(int)          HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled);
     85VMMR0DECL(int)          HWACCMR0EnterSwitcher(PVM pVM, VMMSWITCHER enmSwitcher, bool *pfVTxDisabled);
     86VMMR0DECL(void)         HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled);
    8687
    8788VMMR0DECL(void)         HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize);
  • trunk/src/VBox/HostDrivers/Support/Makefile.kmk

    r43315 r43379  
    267267 endif
    268268 #VBoxDrv_DEFS.debug      += DEBUG_DARWIN_GIP
    269  #VBoxDrv_DEFS.darwin     := VBOX_WITH_HOST_VMX - break raw-mode, hack+enable after 4.2.0!
     269 #VBoxDrv_DEFS.darwin     := VBOX_WITH_HOST_VMX
    270270 VBoxDrv_DEFS.linux      := \
    271271        KBUILD_MODNAME=KBUILD_STR\(vboxdrv\) KBUILD_BASENAME=KBUILD_STR\(vboxdrv\) MODULE CONFIG_VBOXDRV_AS_MISC
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r42024 r43379  
    173173    { "SUPR0ContFree",                          (void *)SUPR0ContFree },
    174174    { "SUPR0EnableVTx",                         (void *)SUPR0EnableVTx },
     175    { "SUPR0SuspendVTxOnCpu",                   (void *)SUPR0SuspendVTxOnCpu },
     176    { "SUPR0ResumeVTxOnCpu",                    (void *)SUPR0ResumeVTxOnCpu },
    175177    { "SUPR0GetPagingMode",                     (void *)SUPR0GetPagingMode },
    176178    { "SUPR0LockMem",                           (void *)SUPR0LockMem },
     
    31883190
    31893191
     3192/**
     3193 * Suspends hardware virtualization extensions using the native OS API.
     3194 *
     3195 * This is called prior to entering raw-mode context.
     3196 *
     3197 * @returns @c true if suspended, @c false if not.
     3198 */
     3199SUPR0DECL(bool) SUPR0SuspendVTxOnCpu(void)
     3200{
     3201#ifdef RT_OS_DARWIN
     3202    return supdrvOSSuspendVTxOnCpu();
     3203#else
     3204    return false;
     3205#endif
     3206}
     3207
     3208
     3209/**
     3210 * Resumes hardware virtualization extensions using the native OS API.
     3211 *
     3212 * This is called after to entering raw-mode context.
     3213 *
     3214 * @param   fSuspended      The return value of SUPR0SuspendVTxOnCpu.
     3215 */
     3216SUPR0DECL(void) SUPR0ResumeVTxOnCpu(bool fSuspended)
     3217{
     3218#ifdef RT_OS_DARWIN
     3219    supdrvOSResumeVTxOnCpu(fSuspended);
     3220#else
     3221    Assert(!fSuspended);
     3222#endif
     3223}
     3224
     3225
    31903226/** @todo document me */
    31913227SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps)
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r41783 r43379  
    194194 *          - Remove RTSpinlockReleaseNoInts.
    195195 */
    196 #define SUPDRV_IOC_VERSION                              0x001a0004
     196#define SUPDRV_IOC_VERSION                              0x001a0005
    197197
    198198/** SUP_IOCTL_COOKIE. */
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r42784 r43379  
    601601bool VBOXCALL   supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt);
    602602int  VBOXCALL   supdrvOSEnableVTx(bool fEnabled);
     603bool VBOXCALL   supdrvOSSuspendVTxOnCpu(void);
     604void VBOXCALL   supdrvOSResumeVTxOnCpu(bool fSuspended);
    603605
    604606/**
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r43358 r43379  
    269269        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    270270        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00190000
    271                                    ? 0x00190003
     271                                   ? 0x001a0005
    272272                                   : SUPDRV_IOC_VERSION & 0xffff0000;
    273273        CookieReq.u.In.u32MinVersion = uMinVersion;
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp

    r43308 r43379  
    4343#include <VBox/version.h>
    4444#include <iprt/asm.h>
     45#include <iprt/asm-amd64-x86.h>
    4546#include <iprt/initterm.h>
    4647#include <iprt/assert.h>
     
    5051#include <iprt/alloc.h>
    5152#include <iprt/power.h>
     53#include <iprt/dbg.h>
    5254#include <VBox/err.h>
    5355#include <VBox/log.h>
     
    99101static IOReturn         VBoxDrvDarwinSleepHandler(void *pvTarget, void *pvRefCon, UInt32 uMessageType, IOService *pProvider, void *pvMessageArgument, vm_size_t argSize);
    100102RT_C_DECLS_END
     103
     104static void             vboxdrvDarwinResolveSymbols(void);
    101105
    102106
     
    211215static int32_t volatile g_cSessions = 0;
    212216/** The notifier handle for the sleep callback handler. */
    213 static IONotifier *g_pSleepNotifier = NULL;
    214 
     217static IONotifier      *g_pSleepNotifier = NULL;
     218
     219/** Pointer to vmx_suspend(). */
     220static PFNRT            g_pfnVmxSuspend = NULL;
     221/** Pointer to vmx_resume(). */
     222static PFNRT            g_pfnVmxResume = NULL;
     223/** Pointer to vmx_use_count. */
     224static int volatile    *g_pVmxUseCount = NULL;
    215225
    216226
     
    267277                            LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));
    268278
     279                        /* Find kernel symbols that are kind of optional. */
     280                        vboxdrvDarwinResolveSymbols();
    269281                        return KMOD_RETURN_SUCCESS;
    270282                    }
     
    296308
    297309/**
     310 * Resolves kernel symbols we want (but may do without).
     311 */
     312static void vboxdrvDarwinResolveSymbols(void)
     313{
     314    RTDBGKRNLINFO hKrnlInfo;
     315    int rc = RTR0DbgKrnlInfoOpen(&hKrnlInfo, 0);
     316    if (RT_SUCCESS(rc))
     317    {
     318        /* The VMX stuff. */
     319        int rc1 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_resume", (void **)&g_pfnVmxResume);
     320        int rc2 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_suspend", (void **)&g_pfnVmxSuspend);
     321        int rc3 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "vmx_use_count", (void **)&g_pVmxUseCount);
     322        if (RT_SUCCESS(rc1) && RT_SUCCESS(rc2) && RT_SUCCESS(rc3))
     323        {
     324            LogRel(("VBoxDrv: vmx_resume=%p vmx_suspend=%p vmx_use_count=%p (%d) cr4=%#x\n",
     325                    g_pfnVmxResume, g_pfnVmxSuspend, g_pVmxUseCount, *g_pVmxUseCount, ASMGetCR4() ));
     326        }
     327        else
     328        {
     329            LogRel(("VBoxDrv: failed to resolve vmx stuff: vmx_resume=%Rrc vmx_suspend=%Rrc vmx_use_count=%Rrc", rc1, rc2, rc3));
     330            g_pfnVmxResume  = NULL;
     331            g_pfnVmxSuspend = NULL;
     332            g_pVmxUseCount  = NULL;
     333        }
     334
     335        RTR0DbgKrnlInfoRelease(hKrnlInfo);
     336    }
     337    else
     338        LogRel(("VBoxDrv: Failed to open kernel symbols, rc=%Rrc\n", rc));
     339}
     340
     341
     342/**
    298343 * Stop the kernel module.
    299344 */
     
    711756
    712757/**
    713  * Enables or disables VT-x using kernel functions.
    714  *
    715  * @returns VBox status code. VERR_NOT_SUPPORTED has a special meaning.
    716  * @param   fEnable     Whether to enable or disable.
     758 * @copydoc SUPR0EnableVTx
    717759 */
    718760int VBOXCALL supdrvOSEnableVTx(bool fEnable)
     
    720762#ifdef VBOX_WITH_HOST_VMX
    721763    int rc;
    722     if (version_major >= 10 /* 10 = 10.6.x = Snow Leopard */)
     764    if (   version_major >= 10 /* 10 = 10.6.x = Snow Leopard */
     765        && g_pfnVmxSuspend
     766        && g_pfnVmxResume
     767        && g_pVmxUseCount)
    723768    {
    724769        if (fEnable)
     
    736781                rc = VERR_UNRESOLVED_ERROR;
    737782            }
     783            LogRel(("VBoxDrv: host_vmxon  -> vmx_use_count=%d rc=%Rrc\n", *g_pVmxUseCount, rc));
    738784        }
    739785        else
     
    741787            host_vmxoff();
    742788            rc = VINF_SUCCESS;
     789            LogRel(("VBoxDrv: host_vmxoff -> vmx_use_count=%d\n", *g_pVmxUseCount));
    743790        }
    744791    }
     
    752799#else
    753800    return VERR_NOT_SUPPORTED;
     801#endif
     802}
     803
     804
     805/**
     806 * @copydoc SUPR0SuspendVTxOnCpu
     807 */
     808bool VBOXCALL supdrvOSSuspendVTxOnCpu(void)
     809{
     810#ifdef VBOX_WITH_HOST_VMX
     811    /*
     812     * Consult the VMX usage counter, don't try suspend if not enabled.
     813     *
     814     * Note!  The host_vmxon/off code is still race prone since, but this is
     815     *        currently the best we can do without always enable VMX when
     816     *        loading the driver.
     817     */
     818    if (   g_pVmxUseCount
     819        && *g_pVmxUseCount > 0)
     820    {
     821        g_pfnVmxSuspend();
     822        return true;
     823    }
     824    return false;
     825#else
     826    return false;
     827#endif
     828}
     829
     830
     831/**
     832 * @copydoc SUPR0ResumeVTxOnCpu
     833 */
     834void VBOXCALL   supdrvOSResumeVTxOnCpu(bool fSuspended)
     835{
     836#ifdef VBOX_WITH_HOST_VMX
     837    /*
     838     * Don't consult the counter here, the state knows better.
     839     * We're executing with interrupts disabled and anyone racing us with
     840     * disabling VT-x will be waiting in the rendezvous code.
     841     */
     842    if (   fSuspended
     843        && g_pfnVmxResume)
     844        g_pfnVmxResume();
     845    else
     846        Assert(!fSuspended);
     847#else
     848    Assert(!fSuspended);
    754849#endif
    755850}
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp

    r43376 r43379  
    16911691 * @returns VBox status code.
    16921692 * @param   pVM             Pointer to the VM.
     1693 * @param   enmSwitcher     The switcher we're about to use.
    16931694 * @param   pfVTxDisabled   Where to store whether VT-x was disabled or not.
    16941695 */
    1695 VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled)
     1696VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, VMMSWITCHER enmSwitcher, bool *pfVTxDisabled)
    16961697{
    16971698    Assert(!(ASMGetFlags() & X86_EFL_IF) || !RTThreadPreemptIsEnabled(NIL_RTTHREAD));
     
    16991700    *pfVTxDisabled = false;
    17001701
    1701     if (   !g_HvmR0.fEnabled
    1702         || !g_HvmR0.vmx.fSupported /* no such issues with AMD-V */
    1703         || !g_HvmR0.fGlobalInit    /* Local init implies the CPU is currently not in VMX root mode. */)
    1704         return VINF_SUCCESS;    /* nothing to do */
    1705 
    1706     switch (VMMGetSwitcher(pVM))
     1702    /* No such issues with AMD-V */
     1703    if (!g_HvmR0.vmx.fSupported)
     1704        return VINF_SUCCESS;
     1705
     1706    /* Check if the swithcing we're up to is safe. */
     1707    switch (enmSwitcher)
    17071708    {
    17081709        case VMMSWITCHER_32_TO_32:
     
    17201721    }
    17211722
     1723    /* When using SUPR0EnableVTx we must let the host suspend and resume VT-x,
     1724       regardless of whether we're currently using VT-x or not. */
     1725    if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
     1726    {
     1727        *pfVTxDisabled = SUPR0SuspendVTxOnCpu();
     1728        return VINF_SUCCESS;
     1729    }
     1730
     1731    /** @todo Check if this code is presumtive wrt other VT-x users on the
     1732     *        system... */
     1733
     1734    /* Nothing to do if we haven't enabled VT-x. */
     1735    if (!g_HvmR0.fEnabled)
     1736        return VINF_SUCCESS;
     1737
     1738    /* Local init implies the CPU is currently not in VMX root mode. */
     1739    if (!g_HvmR0.fGlobalInit)
     1740        return VINF_SUCCESS;
     1741
     1742    /* Ok, disable VT-x. */
    17221743    PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
    17231744    AssertReturn(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ, VERR_HM_IPE_2);
     
    17341755 * switcher turned off paging.
    17351756 *
    1736  * @returns VBox status code.
    17371757 * @param   pVM             Pointer to the VM.
    17381758 * @param   fVTxDisabled    Whether VT-x was disabled or not.
    17391759 */
    1740 VMMR0DECL(int) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled)
     1760VMMR0DECL(void) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled)
    17411761{
    17421762    Assert(!(ASMGetFlags() & X86_EFL_IF));
    17431763
    17441764    if (!fVTxDisabled)
    1745         return VINF_SUCCESS;    /* nothing to do */
    1746 
    1747     Assert(g_HvmR0.fEnabled);
     1765        return;         /* nothing to do */
     1766
    17481767    Assert(g_HvmR0.vmx.fSupported);
    1749     Assert(g_HvmR0.fGlobalInit);
    1750 
    1751     PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
    1752     AssertReturn(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ, VERR_HM_IPE_2);
    1753 
    1754     void           *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
    1755     RTHCPHYS        HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
    1756     return VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
     1768    if (g_HvmR0.vmx.fUsingSUPR0EnableVTx)
     1769        SUPR0ResumeVTxOnCpu(fVTxDisabled);
     1770    else
     1771    {
     1772        Assert(g_HvmR0.fEnabled);
     1773        Assert(g_HvmR0.fGlobalInit);
     1774
     1775        PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
     1776        AssertReturnVoid(pCpu && pCpu->hMemObj != NIL_RTR0MEMOBJ);
     1777
     1778        void           *pvCpuPage     = RTR0MemObjAddress(pCpu->hMemObj);
     1779        RTHCPHYS        HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
     1780        VMXR0EnableCpu(pCpu, pVM, pvCpuPage, HCPhysCpuPage, false);
     1781    }
    17571782}
    17581783
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r43361 r43379  
    137137         */
    138138
    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. */
     139        /** @todo r=bird: Why is this code different than the probing code earlier
     140         *        on? It just sets VMXE if needed and doesn't check that it isn't
     141         *        set.  Mac OS X host_vmxoff may leave this set and we'll fail here
     142         *        and debug-assert in the calling code.  This is what caused the
     143         *        "regression" after backing out the SUPR0EnableVTx code hours before
     144         *        4.2.0GA (reboot fixed the issue).  I've changed here to do the same
     145         *        as the init code. */
     146        uint64_t uCr4 = ASMGetCR4();
     147        if (!(uCr4 & X86_CR4_VMXE))
     148            ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);    /* Make sure the VMX instructions don't cause #UD faults. */
    143149
    144150        /*
     
    148154        if (RT_FAILURE(rc))
    149155        {
    150             ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
     156            ASMSetCR4(uCr4);
    151157            return VERR_VMX_VMXON_FAILED;
    152158        }
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r43303 r43379  
    683683                /* We might need to disable VT-x if the active switcher turns off paging. */
    684684                bool fVTxDisabled;
    685                 int rc = HWACCMR0EnterSwitcher(pVM, &fVTxDisabled);
     685                int rc = HWACCMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
    686686                if (RT_SUCCESS(rc))
    687687                {
     
    999999
    10001000            /* We might need to disable VT-x if the active switcher turns off paging. */
    1001             rc = HWACCMR0EnterSwitcher(pVM, &fVTxDisabled);
     1001            rc = HWACCMR0EnterSwitcher(pVM, pVM->vmm.s.enmSwitcher, &fVTxDisabled);
    10021002            if (RT_FAILURE(rc))
    10031003                return rc;
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