VirtualBox

Changeset 70000 in vbox for trunk/include/VBox


Ignore:
Timestamp:
Dec 8, 2017 5:57:18 AM (7 years ago)
Author:
vboxsync
Message:

VMM: Nested Hw.virt: Make SVM intercept functions smarter. Avoids swapping of modified VMCB state in a lot of
tricky to detect situations and makes it a lot cleaner that the VMCB is only finally restored before the
#VMEXIT is done.

Location:
trunk/include/VBox/vmm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpum.h

    r69764 r70000  
    12031203/** @name Nested Hardware-Virtualization Helpers.
    12041204 * @{  */
    1205 VMM_INT_DECL(bool)      CPUMCanSvmNstGstTakePhysIntr(PCCPUMCTX pCtx);
     1205VMM_INT_DECL(bool)      CPUMCanSvmNstGstTakePhysIntr(PVMCPU pVCpu, PCCPUMCTX pCtx);
    12061206VMM_INT_DECL(bool)      CPUMCanSvmNstGstTakeVirtIntr(PCCPUMCTX pCtx);
    12071207VMM_INT_DECL(uint8_t)   CPUMGetSvmNstGstInterrupt(PCCPUMCTX pCtx);
     
    13271327 *
    13281328 * @returns @c true if in intercept is set, @c false otherwise.
    1329  * @param   pCtx          Pointer to the context.
    1330  * @param   fIntercept    The SVM control/instruction intercept,
    1331  *                        see SVM_CTRL_INTERCEPT_*.
    1332  */
    1333 DECLINLINE(bool) CPUMIsGuestSvmCtrlInterceptSet(PCCPUMCTX pCtx, uint64_t fIntercept)
    1334 {
    1335     Assert(!pCtx->hwvirt.svm.fHMCachedVmcb);
     1329 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
     1330 * @param   pCtx        Pointer to the context.
     1331 * @param   fIntercept  The SVM control/instruction intercept, see
     1332 *                      SVM_CTRL_INTERCEPT_*.
     1333 */
     1334DECLINLINE(bool) CPUMIsGuestSvmCtrlInterceptSet(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fIntercept)
     1335{
    13361336    PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
    1337     return pVmcb && (pVmcb->ctrl.u64InterceptCtrl & fIntercept);
     1337    if (!pVmcb)
     1338        return false;
     1339    if (!pCtx->hwvirt.svm.fHMCachedVmcb)
     1340        return RT_BOOL(pVmcb->ctrl.u64InterceptCtrl & fIntercept);
     1341    return HMIsGuestSvmCtrlInterceptSet(pVCpu, pCtx, fIntercept);
    13381342}
    13391343
    13401344/**
    1341  * Checks if the guest VMCB has the specified CR read intercept
    1342  * active.
     1345 * Checks if the guest VMCB has the specified CR read intercept active.
    13431346 *
    13441347 * @returns @c true if in intercept is set, @c false otherwise.
    1345  * @param   pCtx          Pointer to the context.
    1346  * @param   uCr           The CR register number (0 to 15).
    1347  */
    1348 DECLINLINE(bool) CPUMIsGuestSvmReadCRxInterceptSet(PCCPUMCTX pCtx, uint8_t uCr)
    1349 {
    1350     Assert(!pCtx->hwvirt.svm.fHMCachedVmcb);
     1348 * @param   pVCpu   The cross context virtual CPU structure of the calling EMT.
     1349 * @param   pCtx    Pointer to the context.
     1350 * @param   uCr     The CR register number (0 to 15).
     1351 */
     1352DECLINLINE(bool) CPUMIsGuestSvmReadCRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uCr)
     1353{
     1354    Assert(uCr < 16);
    13511355    PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
    1352     return pVmcb && (pVmcb->ctrl.u16InterceptRdCRx & (1 << uCr));
     1356    if (!pVmcb)
     1357        return false;
     1358    if (!pCtx->hwvirt.svm.fHMCachedVmcb)
     1359        return RT_BOOL(pVmcb->ctrl.u16InterceptRdCRx & (UINT16_C(1) << uCr));
     1360    return HMIsGuestSvmReadCRxInterceptSet(pVCpu, pCtx, uCr);
    13531361}
    13541362
    13551363/**
    1356  * Checks if the guest VMCB has the specified CR write intercept
    1357  * active.
     1364 * Checks if the guest VMCB has the specified CR write intercept active.
    13581365 *
    13591366 * @returns @c true if in intercept is set, @c false otherwise.
    1360  * @param   pCtx          Pointer to the context.
    1361  * @param   uCr           The CR register number (0 to 15).
    1362  */
    1363 DECLINLINE(bool) CPUMIsGuestSvmWriteCRxInterceptSet(PCCPUMCTX pCtx, uint8_t uCr)
    1364 {
    1365     Assert(!pCtx->hwvirt.svm.fHMCachedVmcb);
     1367 * @param   pVCpu   The cross context virtual CPU structure of the calling EMT.
     1368 * @param   pCtx    Pointer to the context.
     1369 * @param   uCr     The CR register number (0 to 15).
     1370 */
     1371DECLINLINE(bool) CPUMIsGuestSvmWriteCRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uCr)
     1372{
     1373    Assert(uCr < 16);
    13661374    PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
    1367     return pVmcb && (pVmcb->ctrl.u16InterceptWrCRx & (1 << uCr));
     1375    if (!pVmcb)
     1376        return false;
     1377    if (!pCtx->hwvirt.svm.fHMCachedVmcb)
     1378        return RT_BOOL(pVmcb->ctrl.u16InterceptWrCRx & (UINT16_C(1) << uCr));
     1379    return HMIsGuestSvmWriteCRxInterceptSet(pVCpu, pCtx, uCr);
    13681380}
    13691381
    13701382/**
    1371  * Checks if the guest VMCB has the specified DR read intercept
    1372  * active.
     1383 * Checks if the guest VMCB has the specified DR read intercept active.
    13731384 *
    13741385 * @returns @c true if in intercept is set, @c false otherwise.
     1386 * @param   pVCpu   The cross context virtual CPU structure of the calling EMT.
    13751387 * @param   pCtx    Pointer to the context.
    13761388 * @param   uDr     The DR register number (0 to 15).
    13771389 */
    1378 DECLINLINE(bool) CPUMIsGuestSvmReadDRxInterceptSet(PCCPUMCTX pCtx, uint8_t uDr)
    1379 {
    1380     Assert(!pCtx->hwvirt.svm.fHMCachedVmcb);
     1390DECLINLINE(bool) CPUMIsGuestSvmReadDRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uDr)
     1391{
     1392    Assert(uDr < 16);
    13811393    PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
    1382     return pVmcb && (pVmcb->ctrl.u16InterceptRdDRx & (1 << uDr));
     1394    if (!pVmcb)
     1395        return false;
     1396    if (!pCtx->hwvirt.svm.fHMCachedVmcb)
     1397        return RT_BOOL(pVmcb->ctrl.u16InterceptRdDRx & (UINT16_C(1) << uDr));
     1398    return HMIsGuestSvmReadDRxInterceptSet(pVCpu, pCtx, uDr);
    13831399}
    13841400
    13851401/**
    1386  * Checks if the guest VMCB has the specified DR write intercept
    1387  * active.
     1402 * Checks if the guest VMCB has the specified DR write intercept active.
    13881403 *
    13891404 * @returns @c true if in intercept is set, @c false otherwise.
     1405 * @param   pVCpu   The cross context virtual CPU structure of the calling EMT.
    13901406 * @param   pCtx    Pointer to the context.
    13911407 * @param   uDr     The DR register number (0 to 15).
    13921408 */
    1393 DECLINLINE(bool) CPUMIsGuestSvmWriteDRxInterceptSet(PCCPUMCTX pCtx, uint8_t uDr)
    1394 {
    1395     Assert(!pCtx->hwvirt.svm.fHMCachedVmcb);
     1409DECLINLINE(bool) CPUMIsGuestSvmWriteDRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uDr)
     1410{
     1411    Assert(uDr < 16);
    13961412    PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
    1397     return pVmcb && (pVmcb->ctrl.u16InterceptWrDRx & (1 << uDr));
     1413    if (!pVmcb)
     1414        return false;
     1415    if (!pCtx->hwvirt.svm.fHMCachedVmcb)
     1416        return RT_BOOL(pVmcb->ctrl.u16InterceptWrDRx & (UINT16_C(1) << uDr));
     1417    return HMIsGuestSvmWriteDRxInterceptSet(pVCpu, pCtx, uDr);
    13981418}
    13991419
    14001420/**
    1401  * Checks if the guest VMCB has the specified exception
    1402  * intercept active.
    1403  *
    1404  * @returns true if in intercept is active, false otherwise.
     1421 * Checks if the guest VMCB has the specified exception intercept active.
     1422 *
     1423 * @returns @c true if in intercept is active, @c false otherwise.
     1424 * @param   pVCpu   The cross context virtual CPU structure of the calling EMT.
    14051425 * @param   pCtx        Pointer to the context.
    14061426 * @param   uVector     The exception / interrupt vector.
    14071427 */
    1408 DECLINLINE(bool) CPUMIsGuestSvmXcptInterceptSet(PCCPUMCTX pCtx, uint8_t uVector)
    1409 {
    1410     Assert(!pCtx->hwvirt.svm.fHMCachedVmcb);
     1428DECLINLINE(bool) CPUMIsGuestSvmXcptInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uVector)
     1429{
    14111430    Assert(uVector < 32);
    14121431    PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
    1413     return pVmcb && (pVmcb->ctrl.u32InterceptXcpt & (UINT32_C(1) << uVector));
     1432    if (!pVmcb)
     1433        return false;
     1434    if (!pCtx->hwvirt.svm.fHMCachedVmcb)
     1435        return RT_BOOL(pVmcb->ctrl.u32InterceptXcpt & (UINT32_C(1) << uVector));
     1436    return HMIsGuestSvmXcptInterceptSet(pVCpu, pCtx, uVector);
    14141437}
    14151438#endif /* !IN_RC */
     
    14181441 * Checks if we are executing inside an SVM nested hardware-virtualized guest.
    14191442 *
    1420  * @returns true if in SVM nested-guest mode, false otherwise.
     1443 * @returns @c true if in SVM nested-guest mode, @c false otherwise.
    14211444 * @param   pCtx        Pointer to the context.
    14221445 */
     
    14311454    return pVmcb && (pVmcb->ctrl.u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMRUN);
    14321455#else
    1433     RT_NOREF(pCtx);
     1456    NOREF(pCtx);
    14341457    return false;
    14351458#endif
     
    14391462 * Checks if we are executing inside a VMX nested hardware-virtualized guest.
    14401463 *
    1441  * @returns true if in VMX nested-guest mode, false otherwise.
     1464 * @returns @c true if in VMX nested-guest mode, @c false otherwise.
    14421465 * @param   pCtx        Pointer to the context.
    14431466 */
     
    14451468{
    14461469    /** @todo Intel. */
    1447     RT_NOREF(pCtx);
     1470    NOREF(pCtx);
    14481471    return false;
    14491472}
     
    14521475 * Checks if we are executing inside a nested hardware-virtualized guest.
    14531476 *
    1454  * @returns true if in SVM/VMX nested-guest mode, false otherwise.
     1477 * @returns @c true if in SVM/VMX nested-guest mode, @c false otherwise.
    14551478 * @param   pCtx        Pointer to the context.
    14561479 */
  • trunk/include/VBox/vmm/hm_svm.h

    r69996 r70000  
    10851085    } while (0)
    10861086
     1087VMM_INT_DECL(bool) HMIsGuestSvmCtrlInterceptSet(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fIntercept);
     1088VMM_INT_DECL(bool) HMIsGuestSvmReadCRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uCr);
     1089VMM_INT_DECL(bool) HMIsGuestSvmWriteCRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uCr);
     1090VMM_INT_DECL(bool) HMIsGuestSvmReadDRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uDr);
     1091VMM_INT_DECL(bool) HMIsGuestSvmWriteDRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uDr);
     1092VMM_INT_DECL(bool) HMIsGuestSvmXcptInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uVector);
     1093VMM_INT_DECL(bool) HMCanSvmNstGstTakePhysIntr(PVMCPU pVCpu, PCCPUMCTX pCtx);
    10871094
    10881095/** @} */
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