VirtualBox

Changeset 100096 in vbox


Ignore:
Timestamp:
Jun 7, 2023 3:14:56 PM (18 months ago)
Author:
vboxsync
Message:

VMM/IEM: Adjusted/reworked the relative jump MCs in the threaded function file. bugref:10369

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

Legend:

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

    r100089 r100096  
    9595
    9696
    97 /** Variant of IEM_MC_REL_JMP_S8_AND_FINISH with instruction length as param. */
    98 #define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED(a_i8, a_cbInstr, a_enmEffOpSize) \
    99     return iemRegRipRelativeJumpS8AndFinishClearingRF(pVCpu, a_cbInstr, (a_i8), a_enmEffOpSize)
     97/** Variant of IEM_MC_REL_JMP_S8_AND_FINISH with instruction length as extra
     98 *  parameter, for use in 16-bit code on a pre-386 CPU. */
     99#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16(a_i8, a_cbInstr) \
     100    return iemRegIp16RelativeJumpS8AndFinishClearingRF(pVCpu, a_cbInstr, (a_i8))
     101
     102/** Variant of IEM_MC_REL_JMP_S8_AND_FINISH with instruction length and operand
     103 * size as extra parameters, for use in 16-bit and 32-bit code on 386 and
     104 * later CPUs. */
     105#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32(a_i8, a_cbInstr, a_enmEffOpSize) \
     106    return iemRegEip32RelativeJumpS8AndFinishClearingRF(pVCpu, a_cbInstr, (a_i8), a_enmEffOpSize)
     107
     108/** Variant of IEM_MC_REL_JMP_S8_AND_FINISH with instruction length and operand
     109 * size as extra parameters, for use in 64-bit code. */
     110#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64(a_i8, a_cbInstr, a_enmEffOpSize) \
     111    return iemRegRip64RelativeJumpS8AndFinishClearingRF(pVCpu, a_cbInstr, (a_i8), a_enmEffOpSize)
     112
    100113#undef  IEM_MC_REL_JMP_S8_AND_FINISH
    101114
    102 /** Variant of IEM_MC_REL_JMP_S16_AND_FINISH with instruction length as param. */
    103 #define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED(a_i16, a_cbInstr) \
    104     return iemRegRipRelativeJumpS16AndFinishClearingRF(pVCpu, a_cbInstr, (a_i16))
     115
     116/** Variant of IEM_MC_REL_JMP_S16_AND_FINISH with instruction length as
     117 *  param, for use in 16-bit code on a pre-386 CPU. */
     118#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16(a_i16, a_cbInstr) \
     119    return iemRegEip32RelativeJumpS16AndFinishClearingRF(pVCpu, a_cbInstr, (a_i16))
     120
     121/** Variant of IEM_MC_REL_JMP_S16_AND_FINISH with instruction length as
     122 *  param, for use in 16-bit and 32-bit code on 386 and later CPUs. */
     123#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32(a_i16, a_cbInstr) \
     124    return iemRegEip32RelativeJumpS16AndFinishClearingRF(pVCpu, a_cbInstr, (a_i16))
     125
     126/** Variant of IEM_MC_REL_JMP_S16_AND_FINISH with instruction length as
     127 *  param, for use in 64-bit code. */
     128#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64(a_i16, a_cbInstr) \
     129    return iemRegRip64RelativeJumpS16AndFinishClearingRF(pVCpu, a_cbInstr, (a_i16))
     130
    105131#undef  IEM_MC_REL_JMP_S16_AND_FINISH
    106132
    107 /** Variant of IEM_MC_REL_JMP_S32_AND_FINISH with instruction length as param. */
    108 #define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED(a_i32, a_cbInstr, a_enmEffOpSize) \
    109     return iemRegRipRelativeJumpS32AndFinishClearingRF(pVCpu, a_cbInstr, (a_i32), a_enmEffOpSize)
     133
     134/** Variant of IEM_MC_REL_JMP_S32_AND_FINISH with instruction length as
     135 *  an extra parameter - dummy for pre-386 variations not eliminated by the
     136 *  python script. */
     137#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC16(a_i32, a_cbInstr) \
     138    do { RT_NOREF(pVCpu, a_i32, a_cbInstr); AssertFailedReturn(VERR_IEM_IPE_9); } while (0)
     139
     140/** Variant of IEM_MC_REL_JMP_S32_AND_FINISH with instruction length as
     141 *  an extra parameter, for use in 16-bit and 32-bit code on 386+. */
     142#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32(a_i32, a_cbInstr) \
     143    return iemRegEip32RelativeJumpS32AndFinishClearingRF(pVCpu, a_cbInstr, (a_i32))
     144
     145/** Variant of IEM_MC_REL_JMP_S32_AND_FINISH with instruction length as
     146 *  an extra parameter, for use in 64-bit code. */
     147#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64(a_i32, a_cbInstr) \
     148    return iemRegRip64RelativeJumpS32AndFinishClearingRF(pVCpu, a_cbInstr, (a_i32))
     149
    110150#undef  IEM_MC_REL_JMP_S32_AND_FINISH
    111151
  • trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py

    r100089 r100096  
    236236                return 'int8_t';
    237237            if sRef.startswith('i16'):
    238                 return 'int32_t';
     238                return 'int16_t';
    239239            if sRef.startswith('i32'):
    240240                return 'int32_t';
     
    404404                                        'IEM_MC_REL_JMP_S16_AND_FINISH', 'IEM_MC_REL_JMP_S32_AND_FINISH'):
    405405                    oNewStmt.asParams.append(self.dParamRefs['cbInstr'][0].sNewName);
    406                     if oNewStmt.sName in ('IEM_MC_REL_JMP_S8_AND_FINISH',  'IEM_MC_REL_JMP_S32_AND_FINISH'):
     406                    if (    oNewStmt.sName in ('IEM_MC_REL_JMP_S8_AND_FINISH', )
     407                        and self.sVariation != self.ksVariation_16_Pre386):
    407408                        oNewStmt.asParams.append(self.dParamRefs['pVCpu->iem.s.enmEffOpSize'][0].sNewName);
    408409                    oNewStmt.sName += '_THREADED';
     
    537538                self.aoParamRefs.append(ThreadedParamRef('IEM_GET_INSTR_LEN(pVCpu)', 'uint4_t', oStmt, sStdRef = 'cbInstr'));
    538539
    539             if oStmt.sName in ('IEM_MC_REL_JMP_S8_AND_FINISH',  'IEM_MC_REL_JMP_S32_AND_FINISH'):
     540            if (    oStmt.sName in ('IEM_MC_REL_JMP_S8_AND_FINISH',)
     541                and self.sVariation != self.ksVariation_16_Pre386):
    540542                self.aoParamRefs.append(ThreadedParamRef('pVCpu->iem.s.enmEffOpSize', 'IEMMODE', oStmt));
    541543
  • trunk/src/VBox/VMM/include/IEMInline.h

    r100089 r100096  
    21382138
    21392139/**
     2140 * Adds a 8-bit signed jump offset to RIP from 64-bit code.
     2141 *
     2142 * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
     2143 * segment limit.
     2144 *
     2145 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     2146 * @param   cbInstr             Instruction size.
     2147 * @param   offNextInstr        The offset of the next instruction.
     2148 * @param   enmEffOpSize        Effective operand size.
     2149 */
     2150DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
     2151                                                                             IEMMODE enmEffOpSize) RT_NOEXCEPT
     2152{
     2153    Assert(IEM_IS_64BIT_CODE(pVCpu));
     2154    Assert(enmEffOpSize == IEMMODE_64BIT || enmEffOpSize == IEMMODE_16BIT);
     2155
     2156    uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
     2157    if (enmEffOpSize == IEMMODE_16BIT)
     2158        uNewRip &= UINT16_MAX;
     2159
     2160    if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
     2161        pVCpu->cpum.GstCtx.rip = uNewRip;
     2162    else
     2163        return iemRaiseGeneralProtectionFault0(pVCpu);
     2164
     2165#ifndef IEM_WITH_CODE_TLB
     2166    iemOpcodeFlushLight(pVCpu, cbInstr);
     2167#endif
     2168
     2169    /*
     2170     * Clear RF and finish the instruction (maybe raise #DB).
     2171     */
     2172    return iemRegFinishClearingRF(pVCpu);
     2173}
     2174
     2175
     2176/**
     2177 * Adds a 8-bit signed jump offset to EIP, on 386 or later from 16-bit or 32-bit
     2178 * code (never 64-bit).
     2179 *
     2180 * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
     2181 * segment limit.
     2182 *
     2183 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     2184 * @param   cbInstr             Instruction size.
     2185 * @param   offNextInstr        The offset of the next instruction.
     2186 * @param   enmEffOpSize        Effective operand size.
     2187 */
     2188DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
     2189                                                                             IEMMODE enmEffOpSize) RT_NOEXCEPT
     2190{
     2191    Assert(!IEM_IS_64BIT_CODE(pVCpu));
     2192    Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
     2193
     2194    uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
     2195    if (enmEffOpSize == IEMMODE_16BIT)
     2196        uNewEip &= UINT16_MAX;
     2197    if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
     2198        pVCpu->cpum.GstCtx.rip = uNewEip;
     2199    else
     2200        return iemRaiseGeneralProtectionFault0(pVCpu);
     2201
     2202#ifndef IEM_WITH_CODE_TLB
     2203    iemOpcodeFlushLight(pVCpu, cbInstr);
     2204#endif
     2205
     2206    /*
     2207     * Clear RF and finish the instruction (maybe raise #DB).
     2208     */
     2209    return iemRegFinishClearingRF(pVCpu);
     2210}
     2211
     2212
     2213/**
     2214 * Adds a 8-bit signed jump offset to IP, on a pre-386 CPU.
     2215 *
     2216 * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
     2217 * segment limit.
     2218 *
     2219 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     2220 * @param   cbInstr             Instruction size.
     2221 * @param   offNextInstr        The offset of the next instruction.
     2222 */
     2223DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegIp16RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
     2224                                                                            int8_t offNextInstr) RT_NOEXCEPT
     2225{
     2226    Assert(!IEM_IS_64BIT_CODE(pVCpu));
     2227
     2228    uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + (int16_t)offNextInstr;
     2229    if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
     2230        pVCpu->cpum.GstCtx.rip = uNewIp;
     2231    else
     2232        return iemRaiseGeneralProtectionFault0(pVCpu);
     2233
     2234#ifndef IEM_WITH_CODE_TLB
     2235    iemOpcodeFlushLight(pVCpu, cbInstr);
     2236#endif
     2237
     2238    /*
     2239     * Clear RF and finish the instruction (maybe raise #DB).
     2240     */
     2241    return iemRegFinishClearingRF(pVCpu);
     2242}
     2243
     2244
     2245/**
     2246 * Adds a 16-bit signed jump offset to RIP from 64-bit code.
     2247 *
     2248 * @returns Strict VBox status code.
     2249 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     2250 * @param   cbInstr             Instruction size.
     2251 * @param   offNextInstr        The offset of the next instruction.
     2252 */
     2253DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
     2254                                                                              int16_t offNextInstr) RT_NOEXCEPT
     2255{
     2256    Assert(IEM_IS_64BIT_CODE(pVCpu));
     2257
     2258    pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr);
     2259
     2260#ifndef IEM_WITH_CODE_TLB
     2261    iemOpcodeFlushLight(pVCpu, cbInstr);
     2262#endif
     2263
     2264    /*
     2265     * Clear RF and finish the instruction (maybe raise #DB).
     2266     */
     2267    return iemRegFinishClearingRF(pVCpu);
     2268}
     2269
     2270
     2271/**
     2272 * Adds a 16-bit signed jump offset to EIP from 16-bit or 32-bit code.
     2273 *
     2274 * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
     2275 * segment limit.
     2276 *
     2277 * @returns Strict VBox status code.
     2278 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     2279 * @param   cbInstr             Instruction size.
     2280 * @param   offNextInstr        The offset of the next instruction.
     2281 *
     2282 * @note    This is also used by 16-bit code in pre-386 mode, as the code is
     2283 *          identical.
     2284 */
     2285DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
     2286                                                                              int16_t offNextInstr) RT_NOEXCEPT
     2287{
     2288    Assert(!IEM_IS_64BIT_CODE(pVCpu));
     2289
     2290    uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
     2291    if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
     2292        pVCpu->cpum.GstCtx.rip = uNewIp;
     2293    else
     2294        return iemRaiseGeneralProtectionFault0(pVCpu);
     2295
     2296#ifndef IEM_WITH_CODE_TLB
     2297    iemOpcodeFlushLight(pVCpu, cbInstr);
     2298#endif
     2299
     2300    /*
     2301     * Clear RF and finish the instruction (maybe raise #DB).
     2302     */
     2303    return iemRegFinishClearingRF(pVCpu);
     2304}
     2305
     2306
     2307/**
     2308 * Adds a 32-bit signed jump offset to RIP from 64-bit code.
     2309 *
     2310 * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
     2311 * segment limit.
     2312 *
     2313 * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
     2314 * only alternative for relative jumps in 64-bit code and that is already
     2315 * handled in the decoder stage.
     2316 *
     2317 * @returns Strict VBox status code.
     2318 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     2319 * @param   cbInstr             Instruction size.
     2320 * @param   offNextInstr        The offset of the next instruction.
     2321 */
     2322DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
     2323                                                                              int32_t offNextInstr) RT_NOEXCEPT
     2324{
     2325    Assert(IEM_IS_64BIT_CODE(pVCpu));
     2326
     2327    uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
     2328    if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
     2329        pVCpu->cpum.GstCtx.rip = uNewRip;
     2330    else
     2331        return iemRaiseGeneralProtectionFault0(pVCpu);
     2332
     2333#ifndef IEM_WITH_CODE_TLB
     2334    iemOpcodeFlushLight(pVCpu, cbInstr);
     2335#endif
     2336
     2337    /*
     2338     * Clear RF and finish the instruction (maybe raise #DB).
     2339     */
     2340    return iemRegFinishClearingRF(pVCpu);
     2341}
     2342
     2343
     2344/**
     2345 * Adds a 32-bit signed jump offset to RIP from 64-bit code.
     2346 *
     2347 * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
     2348 * segment limit.
     2349 *
     2350 * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
     2351 * only alternative for relative jumps in 32-bit code and that is already
     2352 * handled in the decoder stage.
     2353 *
     2354 * @returns Strict VBox status code.
     2355 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     2356 * @param   cbInstr             Instruction size.
     2357 * @param   offNextInstr        The offset of the next instruction.
     2358 */
     2359DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
     2360                                                                              int32_t offNextInstr) RT_NOEXCEPT
     2361{
     2362    Assert(!IEM_IS_64BIT_CODE(pVCpu));
     2363    Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
     2364
     2365    uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
     2366    if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
     2367        pVCpu->cpum.GstCtx.rip = uNewEip;
     2368    else
     2369        return iemRaiseGeneralProtectionFault0(pVCpu);
     2370
     2371#ifndef IEM_WITH_CODE_TLB
     2372    iemOpcodeFlushLight(pVCpu, cbInstr);
     2373#endif
     2374
     2375    /*
     2376     * Clear RF and finish the instruction (maybe raise #DB).
     2377     */
     2378    return iemRegFinishClearingRF(pVCpu);
     2379}
     2380
     2381
     2382/**
    21402383 * Extended version of iemFinishInstructionWithFlagsSet that goes with
    21412384 * iemRegAddToRipAndFinishingClearingRfEx.
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