VirtualBox

Changeset 101448 in vbox for trunk/src


Ignore:
Timestamp:
Oct 16, 2023 8:31:49 AM (19 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
159507
Message:

VMM/IEM: Nested VMX: bugref:10318 Added VMX VM-exit intercepts for RDRAND and RDSEED instructions.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp

    r101304 r101448  
    99659965}
    99669966
     9967
     9968/**
     9969 * Implements 'RDSEED'.
     9970 *
     9971 * @returns VINF_SUCCESS.
     9972 * @param   iReg            The register.
     9973 * @param   enmEffOpSize    The operand size.
     9974 */
     9975IEM_CIMPL_DEF_2(iemCImpl_rdseed, uint8_t, iReg, IEMMODE, enmEffOpSize)
     9976{
     9977    /* Nested-guest VMX intercept. */
     9978    if (   !IEM_VMX_IS_NON_ROOT_MODE(pVCpu)
     9979        || !IEM_VMX_IS_PROCCTLS2_SET(pVCpu, VMX_PROC_CTLS2_RDSEED_EXIT))
     9980    { /* probable */ }
     9981    else
     9982    {
     9983        Log(("rdseed: Guest intercept -> VM-exit\n"));
     9984        IEM_VMX_VMEXIT_INSTR_NEEDS_INFO_RET(pVCpu, VMX_EXIT_RDSEED, VMXINSTRID_RDSEED, cbInstr);
     9985    }
     9986
     9987    uint32_t *pEFlags = &pVCpu->cpum.GstCtx.eflags.uBoth;
     9988    switch (enmEffOpSize)
     9989    {
     9990        case IEMMODE_16BIT:
     9991        {
     9992            PFNIEMAIMPLRDRANDSEEDU16 pfnImpl = IEM_SELECT_HOST_OR_FALLBACK(fRdSeed,
     9993                                                                           &iemAImpl_rdseed_u16,
     9994                                                                           &iemAImpl_rdseed_u16_fallback);
     9995            uint16_t *pu16Dst = iemGRegRefU16(pVCpu, iReg);
     9996            (pfnImpl)(pu16Dst, pEFlags);
     9997            break;
     9998        }
     9999        case IEMMODE_32BIT:
     10000        {
     10001            PFNIEMAIMPLRDRANDSEEDU32 pfnImpl = IEM_SELECT_HOST_OR_FALLBACK(fRdSeed,
     10002                                                                           &iemAImpl_rdseed_u32,
     10003                                                                           &iemAImpl_rdseed_u32_fallback);
     10004            uint32_t *pu32Dst = iemGRegRefU32(pVCpu, iReg);
     10005            (pfnImpl)(pu32Dst, pEFlags);
     10006            iemGRegStoreU32(pVCpu, iReg, *pu32Dst);
     10007            break;
     10008        }
     10009        case IEMMODE_64BIT:
     10010        {
     10011            PFNIEMAIMPLRDRANDSEEDU64 pfnImpl = IEM_SELECT_HOST_OR_FALLBACK(fRdSeed,
     10012                                                                           &iemAImpl_rdseed_u64,
     10013                                                                           &iemAImpl_rdseed_u64_fallback);
     10014            uint64_t *pu64Dst = iemGRegRefU64(pVCpu, iReg);
     10015            (pfnImpl)(pu64Dst, pEFlags);
     10016            break;
     10017        }
     10018        IEM_NOT_REACHED_DEFAULT_CASE_RET();
     10019    }
     10020    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10021}
     10022
     10023
     10024/**
     10025 * Implements 'RDRAND'.
     10026 *
     10027 * @returns VINF_SUCCESS.
     10028 * @param   iReg            The register.
     10029 * @param   enmEffOpSize    The operand size.
     10030 */
     10031IEM_CIMPL_DEF_2(iemCImpl_rdrand, uint8_t, iReg, IEMMODE, enmEffOpSize)
     10032{
     10033    /* Nested-guest VMX intercept. */
     10034    if (   !IEM_VMX_IS_NON_ROOT_MODE(pVCpu)
     10035        || !IEM_VMX_IS_PROCCTLS2_SET(pVCpu, VMX_PROC_CTLS2_RDRAND_EXIT))
     10036    { /* probable */ }
     10037    else
     10038    {
     10039        Log(("rdrand: Guest intercept -> VM-exit\n"));
     10040        IEM_VMX_VMEXIT_INSTR_NEEDS_INFO_RET(pVCpu, VMX_EXIT_RDRAND, VMXINSTRID_RDRAND, cbInstr);
     10041    }
     10042
     10043    uint32_t *pEFlags = &pVCpu->cpum.GstCtx.eflags.uBoth;
     10044    switch (enmEffOpSize)
     10045    {
     10046        case IEMMODE_16BIT:
     10047        {
     10048            PFNIEMAIMPLRDRANDSEEDU16 pfnImpl = IEM_SELECT_HOST_OR_FALLBACK(fRdRand, &iemAImpl_rdrand_u16,
     10049                                                                                    &iemAImpl_rdrand_u16_fallback);
     10050            uint16_t *pu16Dst = iemGRegRefU16(pVCpu, iReg);
     10051            (pfnImpl)(pu16Dst, pEFlags);
     10052            break;
     10053        }
     10054        case IEMMODE_32BIT:
     10055        {
     10056            PFNIEMAIMPLRDRANDSEEDU32 pfnImpl = IEM_SELECT_HOST_OR_FALLBACK(fRdRand, &iemAImpl_rdrand_u32,
     10057                                                                                    &iemAImpl_rdrand_u32_fallback);
     10058            uint32_t *pu32Dst = iemGRegRefU32(pVCpu, iReg);
     10059            (pfnImpl)(pu32Dst, pEFlags);
     10060            iemGRegStoreU32(pVCpu, iReg, *pu32Dst);
     10061            break;
     10062        }
     10063        case IEMMODE_64BIT:
     10064        {
     10065            PFNIEMAIMPLRDRANDSEEDU64 pfnImpl = IEM_SELECT_HOST_OR_FALLBACK(fRdRand, &iemAImpl_rdrand_u64,
     10066                                                                                    &iemAImpl_rdrand_u64_fallback);
     10067            uint64_t *pu64Dst = iemGRegRefU64(pVCpu, iReg);
     10068            (pfnImpl)(pu64Dst, pEFlags);
     10069            break;
     10070        }
     10071        IEM_NOT_REACHED_DEFAULT_CASE_RET();
     10072    }
     10073    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10074}
     10075
    996710076/** @} */
    996810077
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h

    r101387 r101448  
    1251812518    if (IEM_IS_MODRM_REG_MODE(bRm))
    1251912519    {
    12520         /* register destination. */
    12521         switch (pVCpu->iem.s.enmEffOpSize)
    12522         {
    12523             case IEMMODE_16BIT:
    12524                 IEM_MC_BEGIN(2, 0, IEM_MC_F_NOT_286_OR_OLDER, 0);
    12525                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    12526                 IEM_MC_ARG(uint16_t *,      pu16Dst,                0);
    12527                 IEM_MC_ARG(uint32_t *,      pEFlags,                1);
    12528 
    12529                 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
    12530                 IEM_MC_REF_EFLAGS(pEFlags);
    12531                 IEM_MC_CALL_VOID_AIMPL_2(IEM_SELECT_HOST_OR_FALLBACK(fRdRand, iemAImpl_rdrand_u16, iemAImpl_rdrand_u16_fallback),
    12532                                          pu16Dst, pEFlags);
    12533 
    12534                 IEM_MC_ADVANCE_RIP_AND_FINISH();
    12535                 IEM_MC_END();
    12536                 break;
    12537 
    12538             case IEMMODE_32BIT:
    12539                 IEM_MC_BEGIN(2, 0, IEM_MC_F_MIN_386, 0);
    12540                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    12541                 IEM_MC_ARG(uint32_t *,      pu32Dst,                0);
    12542                 IEM_MC_ARG(uint32_t *,      pEFlags,                1);
    12543 
    12544                 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
    12545                 IEM_MC_REF_EFLAGS(pEFlags);
    12546                 IEM_MC_CALL_VOID_AIMPL_2(IEM_SELECT_HOST_OR_FALLBACK(fRdRand, iemAImpl_rdrand_u32, iemAImpl_rdrand_u32_fallback),
    12547                                          pu32Dst, pEFlags);
    12548 
    12549                 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
    12550                 IEM_MC_ADVANCE_RIP_AND_FINISH();
    12551                 IEM_MC_END();
    12552                 break;
    12553 
    12554             case IEMMODE_64BIT:
    12555                 IEM_MC_BEGIN(2, 0, IEM_MC_F_64BIT, 0);
    12556                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    12557                 IEM_MC_ARG(uint64_t *,      pu64Dst,                0);
    12558                 IEM_MC_ARG(uint32_t *,      pEFlags,                1);
    12559 
    12560                 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
    12561                 IEM_MC_REF_EFLAGS(pEFlags);
    12562                 IEM_MC_CALL_VOID_AIMPL_2(IEM_SELECT_HOST_OR_FALLBACK(fRdRand, iemAImpl_rdrand_u64, iemAImpl_rdrand_u64_fallback),
    12563                                          pu64Dst, pEFlags);
    12564 
    12565                 IEM_MC_ADVANCE_RIP_AND_FINISH();
    12566                 IEM_MC_END();
    12567                 break;
    12568 
    12569             IEM_NOT_REACHED_DEFAULT_CASE_RET();
    12570         }
     12520        IEM_MC_BEGIN(2, 0, IEM_MC_F_NOT_286_OR_OLDER, 0);
     12521        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     12522        IEM_MC_ARG_CONST(uint8_t, iReg,        /*=*/IEM_GET_MODRM_RM(pVCpu, bRm), 0);
     12523        IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize,    1);
     12524        IEM_MC_CALL_CIMPL_2(IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT, iemCImpl_rdrand, iReg, enmEffOpSize);
     12525        IEM_MC_END();
    1257112526    }
    1257212527    /* Register only. */
     
    1266312618    {
    1266412619        /* register destination. */
    12665         switch (pVCpu->iem.s.enmEffOpSize)
    12666         {
    12667             case IEMMODE_16BIT:
    12668                 IEM_MC_BEGIN(2, 0, IEM_MC_F_NOT_286_OR_OLDER, 0);
    12669                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    12670                 IEM_MC_ARG(uint16_t *,      pu16Dst,                0);
    12671                 IEM_MC_ARG(uint32_t *,      pEFlags,                1);
    12672 
    12673                 IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
    12674                 IEM_MC_REF_EFLAGS(pEFlags);
    12675                 IEM_MC_CALL_VOID_AIMPL_2(IEM_SELECT_HOST_OR_FALLBACK(fRdSeed, iemAImpl_rdseed_u16, iemAImpl_rdseed_u16_fallback),
    12676                                          pu16Dst, pEFlags);
    12677 
    12678                 IEM_MC_ADVANCE_RIP_AND_FINISH();
    12679                 IEM_MC_END();
    12680                 break;
    12681 
    12682             case IEMMODE_32BIT:
    12683                 IEM_MC_BEGIN(2, 0, IEM_MC_F_MIN_386, 0);
    12684                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    12685                 IEM_MC_ARG(uint32_t *,      pu32Dst,                0);
    12686                 IEM_MC_ARG(uint32_t *,      pEFlags,                1);
    12687 
    12688                 IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
    12689                 IEM_MC_REF_EFLAGS(pEFlags);
    12690                 IEM_MC_CALL_VOID_AIMPL_2(IEM_SELECT_HOST_OR_FALLBACK(fRdSeed, iemAImpl_rdseed_u32, iemAImpl_rdseed_u32_fallback),
    12691                                          pu32Dst, pEFlags);
    12692 
    12693                 IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(pu32Dst);
    12694                 IEM_MC_ADVANCE_RIP_AND_FINISH();
    12695                 IEM_MC_END();
    12696                 break;
    12697 
    12698             case IEMMODE_64BIT:
    12699                 IEM_MC_BEGIN(2, 0, IEM_MC_F_64BIT, 0);
    12700                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    12701                 IEM_MC_ARG(uint64_t *,      pu64Dst,                0);
    12702                 IEM_MC_ARG(uint32_t *,      pEFlags,                1);
    12703 
    12704                 IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
    12705                 IEM_MC_REF_EFLAGS(pEFlags);
    12706                 IEM_MC_CALL_VOID_AIMPL_2(IEM_SELECT_HOST_OR_FALLBACK(fRdSeed, iemAImpl_rdseed_u64, iemAImpl_rdseed_u64_fallback),
    12707                                          pu64Dst, pEFlags);
    12708 
    12709                 IEM_MC_ADVANCE_RIP_AND_FINISH();
    12710                 IEM_MC_END();
    12711                 break;
    12712 
    12713             IEM_NOT_REACHED_DEFAULT_CASE_RET();
    12714         }
     12620        IEM_MC_BEGIN(2, 0, IEM_MC_F_NOT_286_OR_OLDER, 0);
     12621        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     12622        IEM_MC_ARG_CONST(uint8_t, iReg,        /*=*/IEM_GET_MODRM_RM(pVCpu, bRm), 0);
     12623        IEM_MC_ARG_CONST(IEMMODE, enmEffOpSize,/*=*/pVCpu->iem.s.enmEffOpSize,    1);
     12624        IEM_MC_CALL_CIMPL_2(IEM_CIMPL_F_RFLAGS | IEM_CIMPL_F_VMEXIT, iemCImpl_rdseed, iReg, enmEffOpSize);
     12625        IEM_MC_END();
    1271512626    }
    1271612627    /* Register only. */
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r101387 r101448  
    24042404typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLRDRANDSEEDU32,(uint32_t *puDst, uint32_t *pEFlags));
    24052405typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLRDRANDSEEDU64,(uint64_t *puDst, uint32_t *pEFlags));
    2406 typedef FNIEMAIMPLRDRANDSEEDU16  *FNIEMAIMPLPRDRANDSEEDU16;
    2407 typedef FNIEMAIMPLRDRANDSEEDU32  *FNIEMAIMPLPRDRANDSEEDU32;
    2408 typedef FNIEMAIMPLRDRANDSEEDU64  *FNIEMAIMPLPRDRANDSEEDU64;
     2406typedef FNIEMAIMPLRDRANDSEEDU16  *PFNIEMAIMPLRDRANDSEEDU16;
     2407typedef FNIEMAIMPLRDRANDSEEDU32  *PFNIEMAIMPLRDRANDSEEDU32;
     2408typedef FNIEMAIMPLRDRANDSEEDU64  *PFNIEMAIMPLRDRANDSEEDU64;
    24092409
    24102410FNIEMAIMPLRDRANDSEEDU16 iemAImpl_rdrand_u16, iemAImpl_rdrand_u16_fallback;
     
    50995099IEM_CIMPL_PROTO_2(iemCImpl_fxch_underflow, uint8_t, iStReg, uint16_t, uFpuOpcode);
    51005100IEM_CIMPL_PROTO_3(iemCImpl_fcomi_fucomi, uint8_t, iStReg, bool, fUCmp, uint32_t, uPopAndFpuOpcode);
     5101IEM_CIMPL_PROTO_2(iemCImpl_rdseed, uint8_t, iReg, IEMMODE, enmEffOpSize);
     5102IEM_CIMPL_PROTO_2(iemCImpl_rdrand, uint8_t, iReg, IEMMODE, enmEffOpSize);
    51015103/** @} */
    51025104
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