VirtualBox

Ignore:
Timestamp:
Jul 25, 2023 10:34:22 AM (17 months ago)
Author:
vboxsync
Message:

IEM/VMM: Deal with opcode checking cross page boundraries and tentativiely for branches. bugref:10369

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r100672 r100694  
    3939
    4040#include <iprt/setjmp-without-sigmask.h>
     41#include <iprt/list.h>
    4142
    4243
     
    536537
    537538
    538 /** Pointer to a translation block. */
    539 typedef struct IEMTB *PIEMTB;
    540 
    541539/** @name IEM_F_XXX - Execution mode flags (IEMCPU::fExec, IEMTB::fFlags).
    542540 *
     
    720718AssertCompile(  IEM_F_MODE_X86_64BIT              & IEM_F_MODE_X86_PROT_MASK);
    721719AssertCompile(!(IEM_F_MODE_X86_64BIT              & IEM_F_MODE_X86_FLAT_OR_PRE_386_MASK));
     720
     721/**
     722 * A call for the threaded call table.
     723 */
     724typedef struct IEMTHRDEDCALLENTRY
     725{
     726    /** The function to call (IEMTHREADEDFUNCS). */
     727    uint16_t    enmFunction;
     728    uint16_t    uUnused0;
     729
     730    /** Offset into IEMTB::pabOpcodes. */
     731    uint16_t    offOpcode;
     732    /** The opcode length. */
     733    uint8_t     cbOpcode;
     734    /** Index in to IEMTB::aRanges. */
     735    uint8_t     idxRange;
     736
     737    /** Generic parameters. */
     738    uint64_t    auParams[3];
     739} IEMTHRDEDCALLENTRY;
     740AssertCompileSize(IEMTHRDEDCALLENTRY, sizeof(uint64_t) * 4);
     741/** Pointer to a threaded call entry. */
     742typedef struct IEMTHRDEDCALLENTRY *PIEMTHRDEDCALLENTRY;
     743/** Pointer to a const threaded call entry. */
     744typedef IEMTHRDEDCALLENTRY const *PCIEMTHRDEDCALLENTRY;
     745
     746/**
     747 * Translation block.
     748 */
     749#pragma pack(2) /* to prevent the Thrd structure from being padded unnecessarily */
     750typedef struct IEMTB
     751{
     752    /** Next block with the same hash table entry. */
     753    struct IEMTB * volatile pNext;
     754    /** List on the local VCPU for blocks. */
     755    RTLISTNODE          LocalList;
     756
     757    /** @name What uniquely identifies the block.
     758     * @{ */
     759    RTGCPHYS            GCPhysPc;
     760    /** IEMTB_F_XXX (i.e. IEM_F_XXX ++). */
     761    uint32_t            fFlags;
     762    union
     763    {
     764        struct
     765        {
     766            /**< Relevant CS X86DESCATTR_XXX bits. */
     767            uint16_t    fAttr;
     768        } x86;
     769    };
     770    /** @} */
     771
     772    /** Number of opcode ranges. */
     773    uint8_t             cRanges;
     774    /** Statistics: Number of instructions in the block. */
     775    uint8_t             cInstructions;
     776
     777    /** Type specific info. */
     778    union
     779    {
     780        struct
     781        {
     782            /** The call sequence table. */
     783            PIEMTHRDEDCALLENTRY paCalls;
     784            /** Number of calls in paCalls. */
     785            uint16_t            cCalls;
     786            /** Number of calls allocated. */
     787            uint16_t            cAllocated;
     788        } Thrd;
     789    };
     790
     791    /** Number of bytes of opcodes stored in pabOpcodes. */
     792    uint16_t            cbOpcodes;
     793    /** The max storage available in the pabOpcodes block. */
     794    uint16_t            cbOpcodesAllocated;
     795    /** Pointer to the opcode bytes this block was recompiled from. */
     796    uint8_t            *pabOpcodes;
     797
     798    /* --- 64 byte cache line end --- */
     799
     800    /** Opcode ranges.
     801     *
     802     * The opcode checkers and maybe TLB loading functions will use this to figure
     803     * out what to do.  The parameter will specify an entry and the opcode offset to
     804     * start at and the minimum number of bytes to verify (instruction length).
     805     *
     806     * When VT-x and AMD-V looks up the opcode bytes for an exitting instruction,
     807     * they'll first translate RIP (+ cbInstr - 1) to a physical address using the
     808     * code TLB (must have a valid entry for that address) and scan the ranges to
     809     * locate the corresponding opcodes. Probably.
     810     */
     811    struct IEMTBOPCODERANGE
     812    {
     813        /** Offset within pabOpcodes. */
     814        uint16_t        offOpcodes;
     815        /** Number of bytes. */
     816        uint16_t        cbOpcodes;
     817        /** The page offset. */
     818        RT_GCC_EXTENSION
     819        uint16_t        offPhysPage : 12;
     820        /** Unused bits. */
     821        RT_GCC_EXTENSION
     822        uint16_t        u2Unused    :  2;
     823        /** Index into GCPhysPc + aGCPhysPages for the physical page address. */
     824        RT_GCC_EXTENSION
     825        uint16_t        idxPhysPage :  2;
     826    } aRanges[8];
     827
     828    /** Physical pages that this TB covers.
     829     * The GCPhysPc w/o page offset is element zero, so starting here with 1. */
     830    RTGCPHYS            aGCPhysPages[2];
     831} IEMTB;
     832#pragma pack()
     833AssertCompileMemberOffset(IEMTB, x86, 36);
     834AssertCompileMemberOffset(IEMTB, cRanges, 38);
     835AssertCompileMemberOffset(IEMTB, Thrd, 40);
     836AssertCompileMemberOffset(IEMTB, Thrd.cCalls, 48);
     837AssertCompileMemberOffset(IEMTB, cbOpcodes, 52);
     838AssertCompileMemberSize(IEMTB, aRanges[0], 6);
     839AssertCompileSize(IEMTB, 128);
     840/** Pointer to a translation block. */
     841typedef IEMTB *PIEMTB;
     842/** Pointer to a const translation block. */
     843typedef IEMTB const *PCIEMTB;
    722844
    723845
     
    10141136    /** Number of TBs executed. */
    10151137    uint64_t                cTbExec;
     1138    /** Whether we need to check the opcode bytes for the current instruction.
     1139     * This is set by a previous instruction if it modified memory or similar.  */
     1140    bool                    fTbCheckOpcodes;
     1141    /** Whether we just branched and need to start a new opcode range and emit code
     1142     * to do a TLB load and check them again. */
     1143    bool                    fTbBranched;
     1144    /** Set when GCPhysInstrBuf is updated because of a page crossing. */
     1145    bool                    fTbCrossedPage;
    10161146    /** Whether to end the current TB. */
    10171147    bool                    fEndTb;
    10181148    /** Spaced reserved for recompiler data / alignment. */
    1019     bool                    afRecompilerStuff1[7];
     1149    bool                    afRecompilerStuff1[4];
    10201150    /** @} */
    10211151
     
    47644894IEM_CIMPL_PROTO_1(iemCImpl_Hypercall, uint16_t, uDisOpcode); /* both */
    47654895
     4896void            iemThreadedTbObsolete(PVMCPUCC pVCpu, PIEMTB pTb);
     4897IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckMode,
     4898                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4899IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckCsLim,
     4900                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4901IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckCsLimAndOpcodes,
     4902                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4903IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb,
     4904                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4905IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb,
     4906                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4907IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb,
     4908                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4909IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckOpcodes,
     4910                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4911IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb,
     4912                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4913IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckOpcodesLoadingTlb,
     4914                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4915IEM_DECL_IMPL_PROTO(VBOXSTRICTRC, iemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb,
     4916                    (PVMCPU pVCpu, uint64_t uParam0, uint64_t uParam1, uint64_t uParam2));
     4917
    47664918
    47674919extern const PFNIEMOP g_apfnIemInterpretOnlyOneByteMap[256];
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