VirtualBox

Changeset 100096 in vbox for trunk/src/VBox/VMM/include


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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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