VirtualBox

Changeset 62010 in vbox for trunk


Ignore:
Timestamp:
Jul 4, 2016 3:32:28 PM (9 years ago)
Author:
vboxsync
Message:

IEM: Optimized iemSRegGetHid; started a little on TLB code.

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

Legend:

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

    r61968 r62010  
    44894489}
    44904490
     4491#ifdef IEM_WITH_SETJMP
     4492/**
     4493 * See iemRaiseXcptOrInt.  Will not return.
     4494 */
     4495IEM_STATIC DECL_NO_RETURN(void)
     4496iemRaiseXcptOrIntJmp(PIEMCPU     pIemCpu,
     4497                     uint8_t     cbInstr,
     4498                     uint8_t     u8Vector,
     4499                     uint32_t    fFlags,
     4500                     uint16_t    uErr,
     4501                     uint64_t    uCr2)
     4502{
     4503    VBOXSTRICTRC rcStrict = iemRaiseXcptOrInt(pIemCpu, cbInstr, u8Vector, fFlags, uErr, uCr2);
     4504    longjmp(*pIemCpu->CTX_SUFF(pJmpBuf), VBOXSTRICTRC_VAL(rcStrict));
     4505}
     4506#endif
     4507
    44914508
    44924509/** \#DE - 00.  */
     
    46034620}
    46044621
     4622#ifdef IEM_WITH_SETJMP
     4623/** \#GP(0) - 0d.  */
     4624DECL_NO_INLINE(IEM_STATIC, DECL_NO_RETURN(void)) iemRaiseGeneralProtectionFault0Jmp(PIEMCPU pIemCpu)
     4625{
     4626    iemRaiseXcptOrIntJmp(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
     4627}
     4628#endif
     4629
    46054630
    46064631/** \#GP(sel) - 0d.  */
     
    46274652}
    46284653
     4654#ifdef IEM_WITH_SETJMP
     4655/** \#GP(sel) - 0d, longjmp.  */
     4656DECL_NO_INLINE(IEM_STATIC, DECL_NO_RETURN(void)) iemRaiseSelectorBoundsJmp(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess)
     4657{
     4658    NOREF(iSegReg); NOREF(fAccess);
     4659    iemRaiseXcptOrIntJmp(pIemCpu, 0, iSegReg == X86_SREG_SS ? X86_XCPT_SS : X86_XCPT_GP,
     4660                         IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
     4661}
     4662#endif
    46294663
    46304664/** \#GP(sel) - 0d.  */
     
    46354669}
    46364670
     4671#ifdef IEM_WITH_SETJMP
     4672/** \#GP(sel) - 0d, longjmp.  */
     4673DECL_NO_INLINE(IEM_STATIC, DECL_NO_RETURN(void)) iemRaiseSelectorBoundsBySelectorJmp(PIEMCPU pIemCpu, RTSEL Sel)
     4674{
     4675    NOREF(Sel);
     4676    iemRaiseXcptOrIntJmp(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
     4677}
     4678#endif
     4679
    46374680
    46384681/** \#GP(sel) - 0d.  */
     
    46424685    return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
    46434686}
     4687
     4688#ifdef IEM_WITH_SETJMP
     4689/** \#GP(sel) - 0d, longjmp.  */
     4690DECL_NO_INLINE(IEM_STATIC, DECL_NO_RETURN(void)) iemRaiseSelectorInvalidAccessJmp(PIEMCPU pIemCpu, uint32_t iSegReg,
     4691                                                                                  uint32_t fAccess)
     4692{
     4693    NOREF(iSegReg); NOREF(fAccess);
     4694    iemRaiseXcptOrIntJmp(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0);
     4695}
     4696#endif
    46444697
    46454698
     
    49475000{
    49485001    PCPUMCTX    pCtx = pIemCpu->CTX_SUFF(pCtx);
    4949     PCPUMSELREG pSReg;
    4950     switch (iSegReg)
    4951     {
    4952         case X86_SREG_ES: pSReg = &pCtx->es; break;
    4953         case X86_SREG_CS: pSReg = &pCtx->cs; break;
    4954         case X86_SREG_SS: pSReg = &pCtx->ss; break;
    4955         case X86_SREG_DS: pSReg = &pCtx->ds; break;
    4956         case X86_SREG_FS: pSReg = &pCtx->fs; break;
    4957         case X86_SREG_GS: pSReg = &pCtx->gs; break;
    4958         default:
    4959             AssertFailedReturn(NULL);
    4960     }
     5002
     5003    Assert(iSegReg < X86_SREG_COUNT);
     5004    AssertCompileAdjacentMembers(CPUMCTX, es, cs);
     5005    AssertCompileAdjacentMembers(CPUMCTX, cs, ss);
     5006    AssertCompileAdjacentMembers(CPUMCTX, ss, ds);
     5007    AssertCompileAdjacentMembers(CPUMCTX, ds, fs);
     5008    AssertCompileAdjacentMembers(CPUMCTX, fs, gs);
     5009    PCPUMSELREG pSReg = &pCtx->es + iSegReg;
     5010
    49615011#ifdef VBOX_WITH_RAW_MODE_NOT_R0
    4962     if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg))
     5012    if (RT_LIKELY(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg)))
     5013    { /* likely */ }
     5014    else
    49635015        CPUMGuestLazyLoadHiddenSelectorReg(IEMCPU_TO_VMCPU(pIemCpu), pSReg);
    49645016#else
     
    79888040
    79898041#ifdef IEM_WITH_SETJMP
    7990 /**
    7991  * Fetches a data dword, longjmp on error.
     8042
     8043IEM_STATIC RTGCPTR iemMemApplySegmentToReadJmp(PIEMCPU pIemCpu, uint8_t iSegReg, size_t cbMem, RTGCPTR GCPtrMem)
     8044{
     8045    Assert(cbMem >= 1);
     8046    Assert(iSegReg < X86_SREG_COUNT);
     8047
     8048    /*
     8049     * 64-bit mode is simpler.
     8050     */
     8051    if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
     8052    {
     8053        if (iSegReg >= X86_SREG_FS)
     8054        {
     8055            PCPUMSELREGHID pSel = iemSRegGetHid(pIemCpu, iSegReg);
     8056            GCPtrMem += pSel->u64Base;
     8057        }
     8058
     8059        if (RT_LIKELY(X86_IS_CANONICAL(GCPtrMem) && X86_IS_CANONICAL(GCPtrMem + cbMem - 1)))
     8060            return GCPtrMem;
     8061    }
     8062    /*
     8063     * 16-bit and 32-bit segmentation.
     8064     */
     8065    else
     8066    {
     8067        PCPUMSELREGHID pSel   = iemSRegGetHid(pIemCpu, iSegReg);
     8068        if (      (pSel->Attr.u & (X86DESCATTR_P | X86DESCATTR_UNUSABLE | X86_SEL_TYPE_CODE | X86_SEL_TYPE_DOWN))
     8069               == X86DESCATTR_P /* data, expand up */
     8070            ||    (pSel->Attr.u & (X86DESCATTR_P | X86DESCATTR_UNUSABLE | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ))
     8071               == (X86DESCATTR_P | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ) /* code, read-only */ )
     8072        {
     8073            /* expand up */
     8074            uint32_t GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem;
     8075            if (RT_LIKELY(   GCPtrLast32 > pSel->u32Limit
     8076                          && GCPtrLast32 > (uint32_t)GCPtrMem))
     8077                return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
     8078        }
     8079        else if (   (pSel->Attr.u & (X86DESCATTR_P | X86DESCATTR_UNUSABLE | X86_SEL_TYPE_CODE | X86_SEL_TYPE_DOWN))
     8080                 == (X86DESCATTR_P | X86_SEL_TYPE_DOWN) /* data, expand down */ )
     8081        {
     8082            /* expand down */
     8083            uint32_t GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem;
     8084            if (RT_LIKELY(   (uint32_t)GCPtrMem >  pSel->u32Limit
     8085                          && GCPtrLast32        <= (pSel->Attr.n.u1DefBig ? UINT32_MAX : UINT32_C(0xffff))
     8086                          && GCPtrLast32 > (uint32_t)GCPtrMem))
     8087                return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
     8088        }
     8089        else
     8090            iemRaiseSelectorInvalidAccessJmp(pIemCpu, iSegReg, IEM_ACCESS_DATA_R);
     8091        iemRaiseSelectorBoundsJmp(pIemCpu, iSegReg, IEM_ACCESS_DATA_R);
     8092    }
     8093    iemRaiseGeneralProtectionFault0Jmp(pIemCpu);
     8094}
     8095
     8096
     8097/**
     8098 * Fetches a data dword, longjmp on error, fallback/safe version.
    79928099 *
    79938100 * @returns The dword
     
    79978104 * @param   GCPtrMem            The address of the guest memory.
    79988105 */
    7999 DECL_NO_INLINE(IEM_STATIC, uint32_t) iemMemFetchDataU32Jmp(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem)
    8000 {
    8001     /* The lazy approach for now... */
     8106IEM_STATIC uint32_t iemMemFetchDataU32SafeJmp(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem)
     8107{
    80028108    uint32_t const *pu32Src = (uint32_t const *)iemMemMapJmp(pIemCpu, sizeof(*pu32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
    80038109    uint32_t const  u32Ret  = *pu32Src;
    80048110    iemMemCommitAndUnmapJmp(pIemCpu, (void *)pu32Src, IEM_ACCESS_DATA_R);
    80058111    return u32Ret;
     8112}
     8113
     8114
     8115/**
     8116 * Fetches a data dword, longjmp on error.
     8117 *
     8118 * @returns The dword
     8119 * @param   pIemCpu             The IEM per CPU data.
     8120 * @param   iSegReg             The index of the segment register to use for
     8121 *                              this access.  The base and limits are checked.
     8122 * @param   GCPtrMem            The address of the guest memory.
     8123 */
     8124DECL_NO_INLINE(IEM_STATIC, uint32_t) iemMemFetchDataU32Jmp(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem)
     8125{
     8126# ifdef IEM_WITH_DATA_TLB
     8127    RTGCPTR GCPtrEff = iemMemApplySegmentToReadJmp(pIemCpu, iSegReg, sizeof(uint32_t), GCPtrMem);
     8128    if (RT_LIKELY((GCPtrEff & X86_PAGE_OFFSET_MASK) <= X86_PAGE_SIZE - sizeof(uint32_t)))
     8129    {
     8130        /// @todo more later.
     8131    }
     8132
     8133    return iemMemFetchDataU32SafeJmp(pIemCpu, iSegReg, GCPtrMem);
     8134# else
     8135    /* The lazy approach. */
     8136    uint32_t const *pu32Src = (uint32_t const *)iemMemMapJmp(pIemCpu, sizeof(*pu32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R);
     8137    uint32_t const  u32Ret  = *pu32Src;
     8138    iemMemCommitAndUnmapJmp(pIemCpu, (void *)pu32Src, IEM_ACCESS_DATA_R);
     8139    return u32Ret;
     8140# endif
    80068141}
    80078142#endif
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r62000 r62010  
    319319} IEMTLBENTRY;
    320320AssertCompileSize(IEMTLBENTRY, 32);
     321
     322/** @name IEMTLBE_F_XXX - TLB entry flags (IEMTLBENTRY::fFlagsAndPhysRev)
     323 * @{  */
     324#define IEMTLBE_F_PT_NO_EXEC        RT_BIT_64(0) /**< Page tables: Not executable. */
     325#define IEMTLBE_F_PT_NO_WRITE       RT_BIT_64(1) /**< Page tables: Not writable. */
     326#define IEMTLBE_F_PT_NO_USER        RT_BIT_64(2) /**< Page tables: Not user accessible (supervisor only). */
     327#define IEMTLBE_F_PG_NO_WRITE       RT_BIT_64(3) /**< Phys page:   Not writable (access handler, ROM, whatever). */
     328#define IEMTLBE_F_PG_NO_READ        RT_BIT_64(4) /**< Phys page:   Not readable (MMIO / access handler, ROM) */
     329#define IEMTLBE_F_UNUSED            RT_BIT_64(5) /**< Currently unused. */
     330#define IEMTLBE_F_PT_NO_DIRTY       RT_BIT_64(6) /**< Page tables: Not dirty (needs to be made dirty on write). */
     331#define IEMTLBE_F_NO_MAPPINGR3      RT_BIT_64(7) /**< TLB entry:   The IEMTLBENTRY::pMappingR3 member is invalid. */
     332/** @} */
    321333
    322334
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