VirtualBox

Changeset 102010 in vbox


Ignore:
Timestamp:
Nov 8, 2023 9:36:54 PM (17 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
160109
Message:

VMM/IEM: More on the subject of correctly flushing guest register shadow copies when making CIMPL calls. bugref:10371

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py

    r101849 r102010  
    197197        """
    198198        # Take the threaded function statement list and add detected
    199         # IEM_CIMPL_F_XXX flags to the IEM_MC_BEGIN statement.
     199        # IEM_CIMPL_F_XXX flags to the IEM_MC_BEGIN statement.  Also add
     200        # IEM_MC_F_WITHOUT_FLAGS if this isn't a variation with eflags checking
     201        # and clearing while there are such variations for this function (this
     202        # sounds a bit backwards, but has to be done this way for the use we
     203        # make of the flags in CIMPL calls).
    200204        aoStmts = list(self.oVariation.aoStmtsForThreadedFunction) # type: list(McStmt)
    201205        for iStmt, oStmt in enumerate(aoStmts):
    202             if oStmt.sName == 'IEM_MC_BEGIN' and self.oVariation.oParent.dsCImplFlags:
    203                 oNewStmt = copy.deepcopy(oStmt);
    204                 oNewStmt.asParams[3] = ' | '.join(sorted(self.oVariation.oParent.dsCImplFlags.keys()));
    205                 aoStmts[iStmt] = oNewStmt;
     206            if oStmt.sName == 'IEM_MC_BEGIN':
     207                fWithoutFlags = (    self.oVariation.isWithFlagsCheckingAndClearingVariation()
     208                                 and self.oVariation.oParent.hasWithFlagsCheckingAndClearingVariation());
     209                if fWithoutFlags or self.oVariation.oParent.dsCImplFlags:
     210                    oNewStmt = copy.deepcopy(oStmt);
     211                    if fWithoutFlags:
     212                        oNewStmt.asParams[2] = ' | '.join(sorted(  list(self.oVariation.oParent.oMcBlock.dsMcFlags.keys())
     213                                                                 + ['IEM_MC_F_WITHOUT_FLAGS',] ));
     214                    if self.oVariation.oParent.dsCImplFlags:
     215                        oNewStmt.asParams[3] = ' | '.join(sorted(self.oVariation.oParent.dsCImplFlags.keys()));
     216                    aoStmts[iStmt] = oNewStmt;
    206217
    207218        return iai.McStmt.renderCodeForList(aoStmts, cchIndent);
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r101984 r102010  
    34873487{
    34883488    /*
    3489      * Flush stuff.
    3490      */
    3491     fGstShwFlush = iemNativeCImplFlagsToGuestShadowFlushMask(pReNative->fCImpl, fGstShwFlush | RT_BIT_64(kIemNativeGstReg_Pc));
     3489     * Flush stuff. PC and EFlags are implictly flushed, the latter because we
     3490     * don't do with/without flags variants of defer-to-cimpl stuff at the moment.
     3491     */
     3492    fGstShwFlush = iemNativeCImplFlagsToGuestShadowFlushMask(pReNative->fCImpl,
     3493                                                             fGstShwFlush
     3494                                                             | RT_BIT_64(kIemNativeGstReg_Pc)
     3495                                                             | RT_BIT_64(kIemNativeGstReg_EFlags));
    34923496    iemNativeRegFlushGuestShadows(pReNative, fGstShwFlush);
    34933497
     
    55655569    off = iemNativeEmitLoadGprByBpU32(pReNative, off, X86_GREG_xAX, IEMNATIVE_FP_OFF_IN_SHADOW_ARG0); /* rcStrict (see above) */
    55665570#endif
    5567 /** @todo Always flush EFLAGS if this is an xxF variation. */
    5568     iemNativeRegFlushGuestShadows(pReNative,
    5569                                   iemNativeCImplFlagsToGuestShadowFlushMask(pReNative->fCImpl, RT_BIT_64(kIemNativeGstReg_Pc)) );
     5571    uint64_t fGstShwFlush = iemNativeCImplFlagsToGuestShadowFlushMask(pReNative->fCImpl, RT_BIT_64(kIemNativeGstReg_Pc));
     5572    if (!(pReNative->fMc & IEM_MC_F_WITHOUT_FLAGS)) /** @todo We don't emit with-flags/without-flags variations for CIMPL calls.  */
     5573        fGstShwFlush |= RT_BIT_64(kIemNativeGstReg_EFlags);
     5574    iemNativeRegFlushGuestShadows(pReNative, fGstShwFlush);
    55705575
    55715576    return iemNativeEmitCheckCallRetAndPassUp(pReNative, off, idxInstr);
     
    59475952static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_DeferToCImpl0)
    59485953{
    5949     PFNIEMCIMPL0 const pfnCImpl = (PFNIEMCIMPL0)(uintptr_t)pCallEntry->auParams[0];
    5950     uint8_t const      cbInstr  = (uint8_t)pCallEntry->auParams[1];
    5951     /** @todo Drop this crap hack?
    5952      *  We don't have the flush mask here so we we must pass UINT64_MAX. */
    5953     return iemNativeEmitCImplCall(pReNative, off, pCallEntry->idxInstr, UINT64_MAX, (uintptr_t)pfnCImpl, cbInstr, 0, 0, 0, 0);
     5954    PFNIEMCIMPL0 const pfnCImpl     = (PFNIEMCIMPL0)(uintptr_t)pCallEntry->auParams[0];
     5955    uint8_t const      cbInstr      = (uint8_t)pCallEntry->auParams[1];
     5956    uint64_t const     fGstShwFlush = (uint8_t)pCallEntry->auParams[2];
     5957    return iemNativeEmitCImplCall(pReNative, off, pCallEntry->idxInstr, fGstShwFlush, (uintptr_t)pfnCImpl, cbInstr, 0, 0, 0, 0);
    59545958}
    59555959
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r101984 r102010  
    474474        return '%s_%s%s' % ( sName, self.oParent.oMcBlock.iInFunction, self.sVariation, );
    475475
     476    def isWithFlagsCheckingAndClearingVariation(self):
     477        """
     478        Checks if this is a variation that checks and clears EFLAGS.
     479        """
     480        return self.sVariation in ThreadedFunctionVariation.kdVariationsWithEflagsCheckingAndClearing;
     481
    476482    #
    477483    # Analysis and code morphing.
     
    12941300                                            iai.DecoderFunction('null', 999999999, 'nil', ('','')), 999999999));
    12951301
     1302    def hasWithFlagsCheckingAndClearingVariation(self):
     1303        """
     1304        Check if there is one or more with flags checking and clearing
     1305        variations for this threaded function.
     1306        """
     1307        for sVarWithFlags in ThreadedFunctionVariation.kdVariationsWithEflagsCheckingAndClearing:
     1308            if sVarWithFlags in self.dVariations:
     1309                return True;
     1310        return False;
     1311
     1312    #
     1313    # Analysis and code morphing.
     1314    #
     1315
    12961316    def raiseProblem(self, sMessage):
    12971317        """ Raises a problem. """
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdTables.h

    r101984 r102010  
    8383
    8484#include "IEMThreadedFunctions.h"
     85#include "IEMN8veRecompiler.h" /* For a_fGstShwFlush and iemThreadedRecompilerMcDeferToCImpl0. */
    8586
    8687
     
    302303#undef IEM_MC_DEFER_TO_CIMPL_0_RET
    303304#define IEM_MC_DEFER_TO_CIMPL_0_RET(a_fFlags, a_fGstShwFlush, a_pfnCImpl) \
    304     return iemThreadedRecompilerMcDeferToCImpl0(pVCpu, a_fFlags, a_pfnCImpl)
    305 
    306 DECLINLINE(VBOXSTRICTRC) iemThreadedRecompilerMcDeferToCImpl0(PVMCPUCC pVCpu, uint32_t fFlags, PFNIEMCIMPL0 pfnCImpl)
     305    return iemThreadedRecompilerMcDeferToCImpl0(pVCpu, a_fFlags, a_fGstShwFlush, a_pfnCImpl)
     306
     307DECLINLINE(VBOXSTRICTRC)
     308iemThreadedRecompilerMcDeferToCImpl0(PVMCPUCC pVCpu, uint32_t fFlags, uint64_t fGstShwFlush, PFNIEMCIMPL0 pfnCImpl)
    307309{
    308     Log8(("CImpl0: %04x:%08RX64 LB %#x: %#x %p\n",
    309           pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, IEM_GET_INSTR_LEN(pVCpu), fFlags, pfnCImpl));
     310    Log8(("CImpl0: %04x:%08RX64 LB %#x: %#x %#RX64 %p\n",
     311          pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, IEM_GET_INSTR_LEN(pVCpu), fFlags, fGstShwFlush, pfnCImpl));
    310312    pVCpu->iem.s.fTbCurInstr = fFlags;
    311313
    312314    IEM_MC2_BEGIN_EMIT_CALLS(fFlags & IEM_CIMPL_F_CHECK_IRQ_BEFORE);
    313     IEM_MC2_EMIT_CALL_2(kIemThreadedFunc_BltIn_DeferToCImpl0, (uintptr_t)pfnCImpl, IEM_GET_INSTR_LEN(pVCpu));
     315    IEM_MC2_EMIT_CALL_3(kIemThreadedFunc_BltIn_DeferToCImpl0, (uintptr_t)pfnCImpl, IEM_GET_INSTR_LEN(pVCpu), fGstShwFlush);
    314316    if (   (fFlags & (IEM_CIMPL_F_MODE | IEM_CIMPL_F_VMEXIT))
    315317        && !(fFlags & (IEM_CIMPL_F_END_TB | IEM_CIMPL_F_BRANCH_FAR)))
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r101984 r102010  
    560560#define IEM_MC_F_64BIT              RT_BIT_32(6)
    561561#define IEM_MC_F_NOT_64BIT          RT_BIT_32(7)
     562/** This is set by IEMAllN8vePython.py to indicate a variation without the
     563 * flags-clearing-and-checking, when there is also a variation with that.
     564 * @note Do not use this manully, it's only for python and for testing in
     565 *       the native recompiler! */
     566#define IEM_MC_F_WITHOUT_FLAGS      RT_BIT_32(8)
    562567/** @} */
    563568
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