VirtualBox

Changeset 20421 in vbox


Ignore:
Timestamp:
Jun 9, 2009 9:34:53 AM (16 years ago)
Author:
vboxsync
Message:

Rewrote rem notification handling.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vm.h

    r20399 r20421  
    946946/** @def VM_REM_SIZE
    947947 * Must be multiple of 32 and coherent with REM_ENV_SIZE from REMInternal.h. */
    948 #if GC_ARCH_BITS == 32
    949 # define VM_REM_SIZE        (HC_ARCH_BITS == 32 ? 0x10800 : 0x10800)
    950 #else
    951 # define VM_REM_SIZE        (HC_ARCH_BITS == 32 ? 0x10900 : 0x10900)
    952 #endif
     948# define VM_REM_SIZE        0x10A00
    953949        char        padding[VM_REM_SIZE];   /* multiple of 32 */
    954950    } rem;
  • trunk/src/VBox/VMM/REMInternal.h

    r19660 r20421  
    107107        uint64_t                padding[5];
    108108    } u;
     109    uint32_t                    idxSelf;
     110    uint32_t                    idxNext;
    109111} REMHANDLERNOTIFICATION, *PREMHANDLERNOTIFICATION;
    110112
     
    166168     * These instructions are replayed when entering REM. */
    167169    RTGCPTR                 aGCPtrInvalidatedPages[48];
    168     /** The number of recorded handler notifications. */
    169     RTUINT volatile         cHandlerNotifications;
    170     RTUINT                  padding0; /**< Padding. */
     170
    171171    /** Array of recorded handler noticications.
    172172     * These are replayed when entering REM. */
    173173    REMHANDLERNOTIFICATION  aHandlerNotifications[32];
     174    volatile uint32_t       idxPendingList;
     175    volatile uint32_t       idxFreeList;
    174176
    175177    /** MMIO memory type.
     
    211213    uint32_t                abPadding[HC_ARCH_BITS == 32 ? 6 : 4];
    212214
    213 #if GC_ARCH_BITS == 32
    214 # define REM_ENV_SIZE        (HC_ARCH_BITS == 32 ? 0xff00 : 0xff00)
    215 #else
    216 # define REM_ENV_SIZE        (HC_ARCH_BITS == 32 ? 0xff00 : 0xff00)
    217 #endif
     215# define REM_ENV_SIZE       0xff00
    218216
    219217    /** Recompiler CPU state. */
  • trunk/src/VBox/VMM/VMMAll/REMAll.cpp

    r20410 r20421  
    8282    AssertReleaseMsgFailed(("Ring 3 call????.\n"));
    8383#endif
    84     Assert(pVM->rem.s.cHandlerNotifications == 0);
    85 }
    86 
     84}
     85
     86
     87/**
     88 * Insert pending notification
     89 *
     90 * @param   pVM             VM Handle.
     91 * @param   pRec            Notification record to insert
     92 */
     93static void remNotifyHandlerInsert(PVM pVM, PREMHANDLERNOTIFICATION pRec)
     94{
     95    uint32_t idxFree;
     96    uint32_t idxNext;
     97    PREMHANDLERNOTIFICATION pFree;
     98
     99    /* Fetch a free record. */
     100    do
     101    {
     102        idxFree = pVM->rem.s.idxFreeList;
     103        if (idxFree == -1)
     104        {
     105            pFree = NULL;
     106            break;
     107        }
     108        pFree = &pVM->rem.s.aHandlerNotifications[idxFree]; 
     109    } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxFreeList, pFree->idxNext, idxFree));
     110
     111    if (!pFree)
     112    {
     113        remFlushHandlerNotifications(pVM);
     114        return;
     115    }
     116
     117    /* Copy the record. */
     118    *pFree = *pRec;
     119    pFree->idxSelf = idxFree; /* was trashed */
     120
     121    /* Insert it into the pending list. */
     122    do
     123    {
     124        idxNext = pVM->rem.s.idxPendingList;
     125        pFree->idxNext = idxNext;
     126    } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxPendingList, idxFree, idxNext));
     127
     128    VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY);
     129}
    87130
    88131/**
     
    97140VMMDECL(void) REMNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler)
    98141{
    99     if (pVM->rem.s.cHandlerNotifications >= RT_ELEMENTS(pVM->rem.s.aHandlerNotifications))
    100         remFlushHandlerNotifications(pVM);
    101     PREMHANDLERNOTIFICATION pRec = &pVM->rem.s.aHandlerNotifications[pVM->rem.s.cHandlerNotifications++];
    102     pRec->enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_REGISTER;
    103     pRec->u.PhysicalRegister.enmType = enmType;
    104     pRec->u.PhysicalRegister.GCPhys = GCPhys;
    105     pRec->u.PhysicalRegister.cb = cb;
    106     pRec->u.PhysicalRegister.fHasHCHandler = fHasHCHandler;
    107     VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY);
     142    REMHANDLERNOTIFICATION Rec;
     143    Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_REGISTER;
     144    Rec.u.PhysicalRegister.enmType = enmType;
     145    Rec.u.PhysicalRegister.GCPhys = GCPhys;
     146    Rec.u.PhysicalRegister.cb = cb;
     147    Rec.u.PhysicalRegister.fHasHCHandler = fHasHCHandler;
     148    remNotifyHandlerInsert(pVM, &Rec);
    108149}
    109150
     
    121162VMMDECL(void) REMNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
    122163{
    123     if (pVM->rem.s.cHandlerNotifications >= RT_ELEMENTS(pVM->rem.s.aHandlerNotifications))
    124         remFlushHandlerNotifications(pVM);
    125     PREMHANDLERNOTIFICATION pRec = &pVM->rem.s.aHandlerNotifications[pVM->rem.s.cHandlerNotifications++];
    126     pRec->enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_DEREGISTER;
    127     pRec->u.PhysicalDeregister.enmType = enmType;
    128     pRec->u.PhysicalDeregister.GCPhys = GCPhys;
    129     pRec->u.PhysicalDeregister.cb = cb;
    130     pRec->u.PhysicalDeregister.fHasHCHandler = fHasHCHandler;
    131     pRec->u.PhysicalDeregister.fRestoreAsRAM = fRestoreAsRAM;
    132     VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY);
     164    REMHANDLERNOTIFICATION Rec;
     165    Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_DEREGISTER;
     166    Rec.u.PhysicalDeregister.enmType = enmType;
     167    Rec.u.PhysicalDeregister.GCPhys = GCPhys;
     168    Rec.u.PhysicalDeregister.cb = cb;
     169    Rec.u.PhysicalDeregister.fHasHCHandler = fHasHCHandler;
     170    Rec.u.PhysicalDeregister.fRestoreAsRAM = fRestoreAsRAM;
     171    remNotifyHandlerInsert(pVM, &Rec);
    133172}
    134173
     
    147186VMMDECL(void) REMNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
    148187{
    149     if (pVM->rem.s.cHandlerNotifications >= RT_ELEMENTS(pVM->rem.s.aHandlerNotifications))
    150         remFlushHandlerNotifications(pVM);
    151     PREMHANDLERNOTIFICATION pRec = &pVM->rem.s.aHandlerNotifications[pVM->rem.s.cHandlerNotifications++];
    152     pRec->enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_MODIFY;
    153     pRec->u.PhysicalModify.enmType = enmType;
    154     pRec->u.PhysicalModify.GCPhysOld = GCPhysOld;
    155     pRec->u.PhysicalModify.GCPhysNew = GCPhysNew;
    156     pRec->u.PhysicalModify.cb = cb;
    157     pRec->u.PhysicalModify.fHasHCHandler = fHasHCHandler;
    158     pRec->u.PhysicalModify.fRestoreAsRAM = fRestoreAsRAM;
    159     VM_FF_SET(pVM, VM_FF_REM_HANDLER_NOTIFY);
     188    REMHANDLERNOTIFICATION Rec;
     189    Rec.enmKind = REMHANDLERNOTIFICATIONKIND_PHYSICAL_MODIFY;
     190    Rec.u.PhysicalModify.enmType = enmType;
     191    Rec.u.PhysicalModify.GCPhysOld = GCPhysOld;
     192    Rec.u.PhysicalModify.GCPhysNew = GCPhysNew;
     193    Rec.u.PhysicalModify.cb = cb;
     194    Rec.u.PhysicalModify.fHasHCHandler = fHasHCHandler;
     195    Rec.u.PhysicalModify.fRestoreAsRAM = fRestoreAsRAM;
     196    remNotifyHandlerInsert(pVM, &Rec);
    160197}
    161198
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r20151 r20421  
    725725    GEN_CHECK_OFF(REM, cCanExecuteRaw);
    726726    GEN_CHECK_OFF(REM, aGCPtrInvalidatedPages);
    727     GEN_CHECK_OFF(REM, cHandlerNotifications);
     727    GEN_CHECK_OFF(REM, idxPendingList);
    728728    GEN_CHECK_OFF(REM, aHandlerNotifications);
     729    GEN_CHECK_OFF(REM, idxFreeList);
    729730    GEN_CHECK_OFF(REM, rc);
    730731    GEN_CHECK_OFF(REM, StatsInQEMU);
  • trunk/src/recompiler/VBoxRecompiler.c

    r20408 r20421  
    106106static void     remR3HandlerWriteU32(void *pvVM, target_phys_addr_t GCPhys, uint32_t u32);
    107107
     108static void remR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
     109static void remR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler);
     110static void remR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
    108111
    109112/*******************************************************************************
     
    406409# endif
    407410#endif
     411
     412    PREMHANDLERNOTIFICATION pCur;
     413    unsigned i;
     414
     415    pVM->rem.s.idxPendingList = -1;
     416    pVM->rem.s.idxFreeList    = 0;
     417
     418    for (i = 0 ; i < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1; i++)
     419    {
     420        pCur = &pVM->rem.s.aHandlerNotifications[i];
     421        pCur->idxNext = i + 1;
     422        pCur->idxSelf = i;
     423    }
     424
     425    pCur = &pVM->rem.s.aHandlerNotifications[RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1];
     426    pCur->idxNext = -1;
     427    pCur->idxSelf = RT_ELEMENTS(pVM->rem.s.aHandlerNotifications) - 1;
    408428
    409429    return rc;
     
    18731893    }
    18741894
    1875     /* Replay notification changes? */
    1876     if (pVM->rem.s.cHandlerNotifications)
    1877         REMR3ReplayHandlerNotifications(pVM);
     1895    /* Replay notification changes. */
     1896    REMR3ReplayHandlerNotifications(pVM);
    18781897
    18791898    /* Update MSRs; before CRx registers! */
     
    26932712REMR3DECL(void) REMR3ReplayHandlerNotifications(PVM pVM)
    26942713{
    2695     Assert(EMRemIsLockOwner(pVM));
    2696 
    26972714    /*
    26982715     * Replay the flushes.
     
    27032720    if (VM_FF_TESTANDCLEAR(pVM, VM_FF_REM_HANDLER_NOTIFY_BIT))
    27042721    {
    2705         RTUINT i;
    2706         const RTUINT c = pVM->rem.s.cHandlerNotifications;
    2707 
    2708         pVM->rem.s.cHandlerNotifications = 0;
    2709         for (i = 0; i < c; i++)
     2722        /* Lockless purging of pending notifications. */
     2723        uint32_t idxReqs = ASMAtomicXchgU32(&pVM->rem.s.idxPendingList, -1);
     2724        if (idxReqs == -1)
     2725            return;
     2726
     2727        Assert(idxReqs < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications));
     2728        PREMHANDLERNOTIFICATION pReqs = &pVM->rem.s.aHandlerNotifications[idxReqs];
     2729
     2730        /*
     2731         * Reverse the list to process it in FIFO order.
     2732         */
     2733        PREMHANDLERNOTIFICATION pReq = pReqs;
     2734        pReqs = NULL;
     2735        while (pReq)
    27102736        {
    2711             PREMHANDLERNOTIFICATION pRec = &pVM->rem.s.aHandlerNotifications[i];
     2737            PREMHANDLERNOTIFICATION pCur = pReq;
     2738
     2739            if (pReq->idxNext != -1)
     2740            {
     2741                Assert(pReq->idxNext < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications));
     2742                pReq = &pVM->rem.s.aHandlerNotifications[pReq->idxNext];
     2743            }
     2744            else
     2745                pReq = NULL;
     2746
     2747            pCur->idxNext = (pReqs) ? pReqs->idxSelf : -1;
     2748            pReqs = pCur;
     2749        }
     2750
     2751        while (pReqs)
     2752        {
     2753            PREMHANDLERNOTIFICATION pRec = pReqs;
     2754
    27122755            switch (pRec->enmKind)
    27132756            {
    27142757                case REMHANDLERNOTIFICATIONKIND_PHYSICAL_REGISTER:
    2715                     REMR3NotifyHandlerPhysicalRegister(pVM,
     2758                    remR3NotifyHandlerPhysicalRegister(pVM,
    27162759                                                    pRec->u.PhysicalRegister.enmType,
    27172760                                                    pRec->u.PhysicalRegister.GCPhys,
     
    27212764
    27222765                case REMHANDLERNOTIFICATIONKIND_PHYSICAL_DEREGISTER:
    2723                     REMR3NotifyHandlerPhysicalDeregister(pVM,
     2766                    remR3NotifyHandlerPhysicalDeregister(pVM,
    27242767                                                        pRec->u.PhysicalDeregister.enmType,
    27252768                                                        pRec->u.PhysicalDeregister.GCPhys,
     
    27302773
    27312774                case REMHANDLERNOTIFICATIONKIND_PHYSICAL_MODIFY:
    2732                     REMR3NotifyHandlerPhysicalModify(pVM,
     2775                    remR3NotifyHandlerPhysicalModify(pVM,
    27332776                                                    pRec->u.PhysicalModify.enmType,
    27342777                                                    pRec->u.PhysicalModify.GCPhysOld,
     
    27432786                    break;
    27442787            }
     2788            if (pReqs->idxNext != -1)
     2789            {
     2790                AssertMsg(pReqs->idxNext < RT_ELEMENTS(pVM->rem.s.aHandlerNotifications), ("pReqs->idxNext=%d\n", pReqs->idxNext));
     2791                pReqs = &pVM->rem.s.aHandlerNotifications[pReqs->idxNext];
     2792            }
     2793            else
     2794                pReqs = NULL;
     2795
     2796            /* Put the record back into the free list */
     2797            uint32_t idxNext;
     2798
     2799            do
     2800            {
     2801                idxNext = pVM->rem.s.idxFreeList;
     2802                pRec->idxNext = idxNext;
     2803            } while (!ASMAtomicCmpXchgU32(&pVM->rem.s.idxFreeList, pRec->idxSelf, idxNext));
    27452804        }
    27462805    }
     
    29312990 *          Handler memory type to memory which has no HC handler.
    29322991 */
    2933 REMR3DECL(void) REMR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler)
     2992static void remR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler)
    29342993{
    29352994    Log(("REMR3NotifyHandlerPhysicalRegister: enmType=%d GCPhys=%RGp cb=%RGp fHasHCHandler=%d\n",
    29362995          enmType, GCPhys, cb, fHasHCHandler));
     2996
    29372997    VM_ASSERT_EMT(pVM);
    29382998    Assert(RT_ALIGN_T(GCPhys, PAGE_SIZE, RTGCPHYS) == GCPhys);
     
    29423002    EMRemLock(pVM);
    29433003#endif
    2944     if (pVM->rem.s.cHandlerNotifications)
    2945         REMR3ReplayHandlerNotifications(pVM);
    29463004
    29473005    Assert(!pVM->rem.s.fIgnoreAll);
     
    29603018}
    29613019
     3020/**
     3021 * Notification about a successful PGMR3HandlerPhysicalRegister() call.
     3022 *
     3023 * @param   pVM             VM Handle.
     3024 * @param   enmType         Handler type.
     3025 * @param   GCPhys          Handler range address.
     3026 * @param   cb              Size of the handler range.
     3027 * @param   fHasHCHandler   Set if the handler has a HC callback function.
     3028 *
     3029 * @remark  MMR3PhysRomRegister assumes that this function will not apply the
     3030 *          Handler memory type to memory which has no HC handler.
     3031 */
     3032REMR3DECL(void) REMR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler)
     3033{
     3034    REMR3ReplayHandlerNotifications(pVM);
     3035
     3036    remR3NotifyHandlerPhysicalRegister(pVM, enmType, GCPhys, cb, fHasHCHandler);
     3037}
    29623038
    29633039/**
     
    29713047 * @param   fRestoreAsRAM   Whether the to restore it as normal RAM or as unassigned memory.
    29723048 */
    2973 REMR3DECL(void) REMR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
     3049static void remR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
    29743050{
    29753051    Log(("REMR3NotifyHandlerPhysicalDeregister: enmType=%d GCPhys=%RGp cb=%RGp fHasHCHandler=%RTbool fRestoreAsRAM=%RTbool RAM=%08x\n",
     
    29803056    EMRemLock(pVM);
    29813057#endif
    2982     if (pVM->rem.s.cHandlerNotifications)
    2983         REMR3ReplayHandlerNotifications(pVM);
    29843058
    29853059    Assert(!pVM->rem.s.fIgnoreAll);
     
    30113085}
    30123086
     3087/**
     3088 * Notification about a successful PGMR3HandlerPhysicalDeregister() operation.
     3089 *
     3090 * @param   pVM             VM Handle.
     3091 * @param   enmType         Handler type.
     3092 * @param   GCPhys          Handler range address.
     3093 * @param   cb              Size of the handler range.
     3094 * @param   fHasHCHandler   Set if the handler has a HC callback function.
     3095 * @param   fRestoreAsRAM   Whether the to restore it as normal RAM or as unassigned memory.
     3096 */
     3097REMR3DECL(void) REMR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
     3098{
     3099    REMR3ReplayHandlerNotifications(pVM);
     3100    remR3NotifyHandlerPhysicalDeregister(pVM, enmType, GCPhys, cb, fHasHCHandler, fRestoreAsRAM);
     3101}
     3102
    30133103
    30143104/**
     
    30233113 * @param   fRestoreAsRAM   Whether the to restore it as normal RAM or as unassigned memory.
    30243114 */
    3025 REMR3DECL(void) REMR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
     3115static void remR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
    30263116{
    30273117    Log(("REMR3NotifyHandlerPhysicalModify: enmType=%d GCPhysOld=%RGp GCPhysNew=%RGp cb=%RGp fHasHCHandler=%RTbool fRestoreAsRAM=%RTbool\n",
     
    30333123    EMRemLock(pVM);
    30343124#endif
    3035     if (pVM->rem.s.cHandlerNotifications)
    3036         REMR3ReplayHandlerNotifications(pVM);
    30373125
    30383126    if (fHasHCHandler)
     
    30693157}
    30703158
     3159/**
     3160 * Notification about a successful PGMR3HandlerPhysicalModify() call.
     3161 *
     3162 * @param   pVM             VM Handle.
     3163 * @param   enmType         Handler type.
     3164 * @param   GCPhysOld       Old handler range address.
     3165 * @param   GCPhysNew       New handler range address.
     3166 * @param   cb              Size of the handler range.
     3167 * @param   fHasHCHandler   Set if the handler has a HC callback function.
     3168 * @param   fRestoreAsRAM   Whether the to restore it as normal RAM or as unassigned memory.
     3169 */
     3170REMR3DECL(void) REMR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM)
     3171{
     3172    REMR3ReplayHandlerNotifications(pVM);
     3173
     3174    remR3NotifyHandlerPhysicalModify(pVM, enmType, GCPhysOld, GCPhysNew, cb, fHasHCHandler, fRestoreAsRAM);
     3175}
    30713176
    30723177/**
     
    30843189#ifdef VBOX_STRICT
    30853190    unsigned long off;
    3086     if (pVM->rem.s.cHandlerNotifications)
    3087         REMR3ReplayHandlerNotifications(pVM);
     3191    REMR3ReplayHandlerNotifications(pVM);
    30883192
    30893193    off = get_phys_page_offset(GCPhys);
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