VirtualBox

Changeset 17246 in vbox


Ignore:
Timestamp:
Mar 2, 2009 12:31:50 PM (16 years ago)
Author:
vboxsync
Message:

Allow mixing of VT-x and software virtualization. (untested so far)

Location:
trunk
Files:
6 edited

Legend:

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

    r15609 r17246  
    9090VMMR0DECL(int)  HWACCMR0InitVM(PVM pVM);
    9191VMMR0DECL(int)  HWACCMR0TermVM(PVM pVM);
    92 VMMR0DECL(int)  HWACCMR0EnableAllCpus(PVM pVM, HWACCMSTATE enmNewHwAccmState);
     92VMMR0DECL(int)  HWACCMR0EnableAllCpus(PVM pVM);
     93VMMR0DECL(int)  HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled);
     94VMMR0DECL(int)  HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled);
    9395/** @} */
    9496#endif /* IN_RING0 */
  • trunk/include/VBox/vmm.h

    r17146 r17246  
    114114} VMMCALLHOST;
    115115
    116 RTRCPTR             VMMGetStackRC(PVM pVM);
    117 VMCPUID             VMMGetCpuId(PVM pVM);
    118 PVMCPU              VMMGetCpu(PVM pVM);
    119 VMMDECL(PVMCPU)     VMMGetCpuEx(PVM pVM, RTCPUID idCpu);
    120 VMMDECL(uint32_t)   VMMGetSvnRev(void);
     116RTRCPTR              VMMGetStackRC(PVM pVM);
     117VMCPUID              VMMGetCpuId(PVM pVM);
     118PVMCPU               VMMGetCpu(PVM pVM);
     119VMMDECL(PVMCPU)      VMMGetCpuEx(PVM pVM, RTCPUID idCpu);
     120VMMDECL(uint32_t)    VMMGetSvnRev(void);
     121VMMDECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM);
    121122
    122123/** @def VMMIsHwVirtExtForced
  • trunk/src/VBox/VMM/HWACCM.cpp

    r16422 r17246  
    227227        if (!pVM->hwaccm.s.fAllowed)
    228228# endif
    229             return VM_SET_ERROR(pVM, VERR_INVALID_PARAMETER, "64-bit guest support was requested without also enabling VT-x.");
     229            return VM_SET_ERROR(pVM, VERR_INVALID_PARAMETER, "64-bit guest support was requested without also enabling HWVirtEx (VT-x/AMD-V).");
    230230    }
    231231#else
     
    447447    }
    448448
    449     /*
    450      * Note that we have a global setting for VT-x/AMD-V usage. VMX root mode changes the way the CPU operates. Our 64 bits switcher will trap
    451      * because it turns off paging, which is not allowed in VMX root mode.
    452      *
    453      * To simplify matters we'll just force all running VMs to either use raw or VT-x mode. No mixing allowed in the VT-x case.
    454      * There's no such problem with AMD-V. (@todo)
    455      *
    456      */
    457     /* If we enabled or disabled hwaccm mode, then it can't be changed until all the VMs are shutdown. */
    458     rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_HWACC_ENABLE, (pVM->hwaccm.s.fAllowed) ? HWACCMSTATE_ENABLED : HWACCMSTATE_DISABLED, NULL);
     449    if (!pVM->hwaccm.s.fAllowed)
     450        return VINF_SUCCESS;    /* nothing to do */
     451
     452    /* Enable VT-x or AMD-V on all host CPUs. */
     453    rc = SUPCallVMMR0Ex(pVM->pVMR0, VMMR0_DO_HWACC_ENABLE, 0, NULL);
    459454    if (RT_FAILURE(rc))
    460455    {
    461456        LogRel(("HWACCMR3InitFinalize: SUPCallVMMR0Ex VMMR0_DO_HWACC_ENABLE failed with %Rrc\n", rc));
    462         LogRel(("HWACCMR3InitFinalize: disallowed %s of HWACCM\n", pVM->hwaccm.s.fAllowed ? "enabling" : "disabling"));
    463 
    464 #ifdef RT_OS_DARWIN
    465         /*
    466          * This is 100% fatal if we didn't prepare for a HwVirtExt setup because of
    467          * missing ring-0 allocations. For VMs that require HwVirtExt it doesn't normally
    468          * make sense to try run them in software mode, so fail that too.
    469          */
    470         if (VMMIsHwVirtExtForced(pVM))
    471             VM_SET_ERROR(pVM, rc, "An active VM already uses software virtualization. It is not allowed to "
    472                          "simultaneously use VT-x.");
    473         else
    474             VM_SET_ERROR(pVM, rc, "An active VM already uses Intel VT-x hardware acceleration. It is not "
    475                          "allowed to simultaneously use software virtualization.");
    476457        return rc;
    477 
    478 #else  /* !RT_OS_DARWIN */
    479 
    480         /* Invert the selection */
    481         pVM->hwaccm.s.fAllowed ^= 1;
    482         if (pVM->hwaccm.s.fAllowed)
    483         {
    484             if (pVM->hwaccm.s.vmx.fSupported)
    485                 VM_SET_ERROR(pVM, rc, "An active VM already uses Intel VT-x hardware acceleration. It is not allowed "
    486                                       "to simultaneously use software virtualization.\n");
    487             else
    488                 VM_SET_ERROR(pVM, rc, "An active VM already uses AMD-V hardware acceleration. It is not allowed to "
    489                                       "simultaneously use software virtualization.\n");
    490         }
    491         else
    492             VM_SET_ERROR(pVM, rc, "An active VM already uses software virtualization. It is not allowed to simultaneously "
    493                                   "use VT-x or AMD-V.\n");
    494         return rc;
    495 #endif /* !RT_OS_DARWIN */
    496     }
    497 
    498     if (pVM->hwaccm.s.fAllowed == false)
    499         return VINF_SUCCESS;    /* disabled */
    500 
     458    }
    501459    Assert(!pVM->fHWACCMEnabled || VMMIsHwVirtExtForced(pVM));
    502460
  • trunk/src/VBox/VMM/VMMAll/VMMAll.cpp

    r14875 r17246  
    130130}
    131131
     132/**
     133 * Queries the current switcher
     134 *
     135 * @returns active switcher
     136 * @param   pVM             VM handle.
     137 */
     138VMMDECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM)
     139{
     140    return pVM->vmm.s.enmSwitcher;
     141}
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp

    r16119 r17246  
    563563 * @returns VBox status code.
    564564 * @param   pVM                 The VM to operate on.
    565  * @param   enmNewHwAccmState   New hwaccm state
    566  *
    567  */
    568 VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM, HWACCMSTATE enmNewHwAccmState)
    569 {
    570     Assert(sizeof(HWACCMR0Globals.enmHwAccmState) == sizeof(uint32_t));
     565 *
     566 */
     567VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM)
     568{
     569    AssertCompile(sizeof(HWACCMR0Globals.enmHwAccmState) == sizeof(uint32_t));
    571570
    572571    /* Make sure we don't touch hwaccm after we've disabled hwaccm in preparation of a suspend. */
     
    574573        return VERR_HWACCM_SUSPEND_PENDING;
    575574
    576     if (ASMAtomicCmpXchgU32((volatile uint32_t *)&HWACCMR0Globals.enmHwAccmState, enmNewHwAccmState, HWACCMSTATE_UNINITIALIZED))
     575    if (ASMAtomicCmpXchgU32((volatile uint32_t *)&HWACCMR0Globals.enmHwAccmState, HWACCMSTATE_ENABLED, HWACCMSTATE_UNINITIALIZED))
    577576    {
    578577        int rc;
    579 
    580         /* Don't setup hwaccm as that might not work (vt-x & 64 bits raw mode) */
    581         if (enmNewHwAccmState == HWACCMSTATE_DISABLED)
    582             return VINF_SUCCESS;
    583578
    584579        if (   HWACCMR0Globals.vmx.fSupported
     
    637632        return rc;
    638633    }
    639 
    640     if (HWACCMR0Globals.enmHwAccmState == enmNewHwAccmState)
    641         return VINF_SUCCESS;
    642 
    643     /* Request to change the mode is not allowed */
    644     return VERR_ACCESS_DENIED;
     634    return VINF_SUCCESS;
    645635}
    646636
     
    11311121    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);   
    11321122    if (pVM->hwaccm.s.vmx.fSupported)
    1133         rc  = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnTest64, 5, &aParam[0]);
     1123        rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnTest64, 5, &aParam[0]);
    11341124    else
    11351125        rc = SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnTest64, 5, &aParam[0]);
     
    11731163{
    11741164    return &HWACCMR0Globals.aCpuInfo[idCpu];
     1165}
     1166
     1167/**
     1168 * Disable VT-x if it's active *and* the current switcher turns off paging
     1169 *
     1170 * @returns VBox status code.
     1171 * @param   pVM             VM handle.
     1172 * @param   pfVTxDisabled   VT-x was disabled or not (out)
     1173 */
     1174VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled)
     1175{
     1176    Assert(!(ASMGetFlags() & X86_EFL_IF));
     1177
     1178    *pfVTxDisabled = false;
     1179
     1180    if (    HWACCMR0Globals.enmHwAccmState != HWACCMSTATE_ENABLED
     1181        ||  !HWACCMR0Globals.vmx.fSupported /* no such issues with AMD-V */)
     1182        return VINF_SUCCESS;    /* nothing to do */
     1183
     1184    switch(VMMGetSwitcher(pVM))
     1185    {
     1186    case VMMSWITCHER_32_TO_32:
     1187    case VMMSWITCHER_PAE_TO_PAE:
     1188        return VINF_SUCCESS;    /* safe switchers as they don't turn off paging */
     1189
     1190    case VMMSWITCHER_32_TO_PAE:
     1191    case VMMSWITCHER_PAE_TO_32: /* is this one actually used?? */
     1192    case VMMSWITCHER_AMD64_TO_32:
     1193    case VMMSWITCHER_AMD64_TO_PAE:
     1194        break;                  /* unsafe switchers */
     1195
     1196    default:
     1197        AssertFailed();
     1198        return VERR_INTERNAL_ERROR;
     1199    }
     1200
     1201    PHWACCM_CPUINFO pCpu = HWACCMR0GetCurrentCpu();
     1202    void           *pvPageCpu;
     1203    RTHCPHYS        pPageCpuPhys;
     1204
     1205    AssertReturn(pCpu && pCpu->pMemObj, VERR_INTERNAL_ERROR);
     1206    pvPageCpu    = RTR0MemObjAddress(pCpu->pMemObj);
     1207    pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
     1208
     1209    *pfVTxDisabled = true;
     1210    return VMXR0DisableCpu(pCpu, pvPageCpu, pPageCpuPhys);
     1211}
     1212
     1213/**
     1214 * Reeable VT-x if was active *and* the current switcher turned off paging
     1215 *
     1216 * @returns VBox status code.
     1217 * @param   pVM          VM handle.
     1218 * @param   fVTxDisabled VT-x was disabled or not
     1219 */
     1220VMMR0DECL(int) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled)
     1221{
     1222    Assert(!(ASMGetFlags() & X86_EFL_IF));
     1223
     1224    if (!fVTxDisabled)
     1225        return VINF_SUCCESS;    /* nothing to do */
     1226
     1227    Assert(   HWACCMR0Globals.enmHwAccmState == HWACCMSTATE_ENABLED
     1228           && HWACCMR0Globals.vmx.fSupported);
     1229
     1230    PHWACCM_CPUINFO pCpu = HWACCMR0GetCurrentCpu();
     1231    void           *pvPageCpu;
     1232    RTHCPHYS        pPageCpuPhys;
     1233
     1234    AssertReturn(pCpu && pCpu->pMemObj, VERR_INTERNAL_ERROR);
     1235    pvPageCpu    = RTR0MemObjAddress(pCpu->pMemObj);
     1236    pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
     1237
     1238    return VMXR0EnableCpu(pCpu, pVM, pvPageCpu, pPageCpuPhys);
    11751239}
    11761240
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r16790 r17246  
    501501VMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg)
    502502{
    503     switch (enmOperation)
    504     {
    505         default:
    506             /*
    507              * We're returning VERR_NOT_SUPPORT here so we've got something else
    508              * than -1 which the interrupt gate glue code might return.
    509              */
    510             Log(("operation %#x is not supported\n", enmOperation));
    511             return VERR_NOT_SUPPORTED;
    512     }
     503    /*
     504     * We're returning VERR_NOT_SUPPORT here so we've got something else
     505     * than -1 which the interrupt gate glue code might return.
     506     */
     507    Log(("operation %#x is not supported\n", enmOperation));
     508    return VERR_NOT_SUPPORTED;
    513509}
    514510
     
    543539            {
    544540                RTCCUINTREG uFlags = ASMIntDisableFlags();
    545 
    546 #ifdef VBOX_STRICT
     541                int rc;
     542                bool fVTxDisabled;
     543
    547544                if (RT_UNLIKELY(!PGMGetHyperCR3(pVM)))
    548545                {
    549                     pVM->vmm.s.iLastGZRc = VERR_ACCESS_DENIED;
     546                    pVM->vmm.s.iLastGZRc = VERR_PGM_NO_CR3_SHADOW_ROOT;
    550547                    return;
    551548                }
    552 #endif
     549
     550                /* We might need to disable VT-x if the active switcher turns off paging. */
     551                rc = HWACCMR0EnterSwitcher(pVM, &fVTxDisabled);
     552                if (RT_FAILURE(rc))
     553                {
     554                    pVM->vmm.s.iLastGZRc = rc;
     555                    return;
     556                }
    553557
    554558                TMNotifyStartOfExecution(pVM);
    555                 int rc = pVM->vmm.s.pfnHostToGuestR0(pVM);
     559                rc = pVM->vmm.s.pfnHostToGuestR0(pVM);
    556560                pVM->vmm.s.iLastGZRc = rc;
    557561                TMNotifyEndOfExecution(pVM);
     562
     563                /* Re-enable VT-x if previously turned off. */
     564                HWACCMR0LeaveSwitcher(pVM, fVTxDisabled);
    558565
    559566                if (    rc == VINF_EM_RAW_INTERRUPT
     
    753760         */
    754761        case VMMR0_DO_HWACC_ENABLE:
    755             return HWACCMR0EnableAllCpus(pVM, (HWACCMSTATE)u64Arg);
     762            return HWACCMR0EnableAllCpus(pVM);
    756763
    757764        /*
     
    771778        case VMMR0_DO_CALL_HYPERVISOR:
    772779        {
     780            int rc;
     781            bool fVTxDisabled;
     782
    773783            /* Safety precaution as HWACCM can disable the switcher. */
    774784            Assert(!pVM->vmm.s.fSwitcherDisabled);
     
    776786                return VERR_NOT_SUPPORTED;
    777787
    778 #ifdef VBOX_STRICT
    779788            if (RT_UNLIKELY(!PGMGetHyperCR3(pVM)))
    780                 return VERR_NOT_SUPPORTED;
    781 #endif
     789                return VERR_PGM_NO_CR3_SHADOW_ROOT;
    782790
    783791            RTCCUINTREG fFlags = ASMIntDisableFlags();
    784             int rc = pVM->vmm.s.pfnHostToGuestR0(pVM);
     792
     793            /* We might need to disable VT-x if the active switcher turns off paging. */
     794            rc = HWACCMR0EnterSwitcher(pVM, &fVTxDisabled);
     795            if (RT_FAILURE(rc))
     796                return rc;
     797
     798            rc = pVM->vmm.s.pfnHostToGuestR0(pVM);
     799
     800            /* Re-enable VT-x if previously turned off. */
     801            HWACCMR0LeaveSwitcher(pVM, fVTxDisabled);
     802
    785803            /** @todo dispatch interrupts? */
    786804            ASMSetFlags(fFlags);
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