VirtualBox

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


Ignore:
Timestamp:
Sep 6, 2019 8:09:16 PM (5 years ago)
Author:
vboxsync
Message:

IOM: New I/O port registration code. bugref:9218

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

Legend:

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

    r80281 r80641  
    2828 * @{
    2929 */
     30
     31
     32/**
     33 * Gets the I/O port entry for the specified I/O port in the current context.
     34 *
     35 * @returns Pointer to I/O port entry.
     36 * @returns NULL if no port registered.
     37 *
     38 * @param   pVM             The cross context VM structure.
     39 * @param   Port            The I/O port lookup.
     40 * @param   pidxLastHint    Pointer to IOMCPU::idxIoPortLastRead or
     41 *                          IOMCPU::idxIoPortLastWrite.
     42 *
     43 * @note    In ring-0 it is possible to get an uninitialized entry (pDevIns is
     44 *          NULL, cPorts is 0), in which case there should be ring-3 handlers
     45 *          for the entry.  Use IOMIOPORTENTRYR0::idxSelf to get the ring-3
     46 *          entry.
     47 */
     48DECLINLINE(CTX_SUFF(PIOMIOPORTENTRY)) iomIoPortGetEntry(PVMCC pVM, RTIOPORT uPort, uint16_t *pidxLastHint)
     49{
     50    Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
     51
     52#ifdef IN_RING0
     53    uint32_t              iEnd      = RT_MIN(pVM->iom.s.cIoPortLookupEntries, pVM->iomr0.s.cIoPortAlloc);
     54    PIOMIOPORTLOOKUPENTRY paLookup  = pVM->iomr0.s.paIoPortLookup;
     55#else
     56    uint32_t              iEnd      = pVM->iom.s.cIoPortLookupEntries;
     57    PIOMIOPORTLOOKUPENTRY paLookup  = pVM->iom.s.paIoPortLookup;
     58#endif
     59    if (iEnd > 0)
     60    {
     61        uint32_t iFirst = 0;
     62        uint32_t i      = *pidxLastHint;
     63        if (i < iEnd)
     64        { /* likely */ }
     65        else
     66            i = iEnd / 2;
     67        for (;;)
     68        {
     69            PIOMIOPORTLOOKUPENTRY pCur = &paLookup[i];
     70            if (pCur->uFirstPort > uPort)
     71            {
     72                if (i > iFirst)
     73                    iEnd = i;
     74                else
     75                    return NULL;
     76            }
     77            else if (pCur->uLastPort < uPort)
     78            {
     79                i += 1;
     80                if (i < iEnd)
     81                    iFirst = i;
     82                else
     83                    return NULL;
     84            }
     85            else
     86            {
     87                *pidxLastHint = (uint16_t)i;
     88
     89                /*
     90                 * Translate the 'idx' member into a pointer.
     91                 */
     92                size_t const idx = pCur->idx;
     93#ifdef IN_RING0
     94                AssertMsg(idx < pVM->iom.s.cIoPortRegs && idx < pVM->iomr0.s.cIoPortAlloc,
     95                          ("%#zx vs %#x/%x (port %#x)\n", idx, pVM->iom.s.cIoPortRegs, pVM->iomr0.s.cIoPortMax, uPort));
     96                if (idx < pVM->iomr0.s.cIoPortAlloc)
     97                    return &pVM->iomr0.s.paIoPortRegs[idx];
     98#else
     99                if (idx < pVM->iom.s.cIoPortRegs)
     100                    return &pVM->iom.s.paIoPortRegs[idx];
     101                AssertMsgFailed(("%#zx vs %#x (port %#x)\n", idx, pVM->iom.s.cIoPortRegs, uPort));
     102#endif
     103                break;
     104            }
     105
     106            i = iFirst + (iEnd - iFirst) / 2;
     107        }
     108    }
     109    return NULL;
     110}
     111
     112
     113#ifdef VBOX_WITH_STATISTICS
     114/**
     115 * Gets the I/O port statistics entry .
     116 *
     117 * @returns Pointer to stats.  Instead of NULL, a pointer to IoPortDummyStats is
     118 *          returned, so the caller does not need to check for NULL.
     119 *
     120 * @param   pVM         The cross context VM structure.
     121 * @param   pRegEntry   The I/O port entry to get stats for.
     122 */
     123DECLINLINE(PIOMIOPORTSTATSENTRY) iomIoPortGetStats(PVMCC pVM, CTX_SUFF(PIOMIOPORTENTRY) pRegEntry)
     124{
     125    size_t idxStats = pRegEntry->idxStats;
     126# ifdef IN_RING0
     127    if (idxStats < pVM->iomr0.s.cIoPortStatsAllocation)
     128        return &pVM->iomr0.s.paIoPortStats[idxStats];
     129# else
     130    if (idxStats < pVM->iom.s.cIoPortStats)
     131        return &pVM->iom.s.paIoPortStats[idxStats];
     132# endif
     133    return &pVM->iom.s.IoPortDummyStats;
     134}
     135#endif
     136
    30137
    31138/**
  • trunk/src/VBox/VMM/include/IOMInternal.h

    r80281 r80641  
    139139/** Pointer to I/O port statistics. */
    140140typedef IOMMMIOSTATS *PIOMMMIOSTATS;
     141
     142/**
     143 * I/O port lookup table entry.
     144 */
     145typedef struct IOMIOPORTLOOKUPENTRY
     146{
     147    /** The first port in the range. */
     148    RTIOPORT                    uFirstPort;
     149    /** The last port in the range (inclusive). */
     150    RTIOPORT                    uLastPort;
     151    /** The registration handle/index. */
     152    uint16_t                    idx;
     153} IOMIOPORTLOOKUPENTRY;
     154/** Pointer to an I/O port lookup table entry. */
     155typedef IOMIOPORTLOOKUPENTRY *PIOMIOPORTLOOKUPENTRY;
     156/** Pointer to a const I/O port lookup table entry. */
     157typedef IOMIOPORTLOOKUPENTRY const *PCIOMIOPORTLOOKUPENTRY;
     158
     159/**
     160 * Ring-0 I/O port handle table entry.
     161 */
     162typedef struct IOMIOPORTENTRYR0
     163{
     164    /** Pointer to user argument. */
     165    RTR0PTR                             pvUser;
     166    /** Pointer to the associated device instance, NULL if entry not used. */
     167    R0PTRTYPE(PPDMDEVINS)               pDevIns;
     168    /** Pointer to OUT callback function. */
     169    R0PTRTYPE(PFNIOMIOPORTOUT)          pfnOutCallback;
     170    /** Pointer to IN callback function. */
     171    R0PTRTYPE(PFNIOMIOPORTIN)           pfnInCallback;
     172    /** Pointer to string OUT callback function. */
     173    R0PTRTYPE(PFNIOMIOPORTOUTSTRING)    pfnOutStrCallback;
     174    /** Pointer to string IN callback function. */
     175    R0PTRTYPE(PFNIOMIOPORTINSTRING)     pfnInStrCallback;
     176    /** The entry of the first statistics entry, UINT16_MAX if no stats. */
     177    uint16_t                            idxStats;
     178    /** The number of ports covered by this entry, 0 if entry not used. */
     179    RTIOPORT                            cPorts;
     180    /** Same as the handle index. */
     181    uint16_t                            idxSelf;
     182} IOMIOPORTENTRYR0;
     183/** Pointer to a ring-0 I/O port handle table entry. */
     184typedef IOMIOPORTENTRYR0 *PIOMIOPORTENTRYR0;
     185/** Pointer to a const ring-0 I/O port handle table entry. */
     186typedef IOMIOPORTENTRYR0 const *PCIOMIOPORTENTRYR0;
     187
     188/**
     189 * Ring-3 I/O port handle table entry.
     190 */
     191typedef struct IOMIOPORTENTRYR3
     192{
     193    /** Pointer to user argument. */
     194    RTR3PTR                             pvUser;
     195    /** Pointer to the associated device instance. */
     196    R3PTRTYPE(PPDMDEVINS)               pDevIns;
     197    /** Pointer to OUT callback function. */
     198    R3PTRTYPE(PFNIOMIOPORTOUT)          pfnOutCallback;
     199    /** Pointer to IN callback function. */
     200    R3PTRTYPE(PFNIOMIOPORTIN)           pfnInCallback;
     201    /** Pointer to string OUT callback function. */
     202    R3PTRTYPE(PFNIOMIOPORTOUTSTRING)    pfnOutStrCallback;
     203    /** Pointer to string IN callback function. */
     204    R3PTRTYPE(PFNIOMIOPORTINSTRING)     pfnInStrCallback;
     205    /** Description / Name. For easing debugging. */
     206    R3PTRTYPE(const char *)             pszDesc;
     207    /** PCI device the registration is associated with. */
     208    R3PTRTYPE(PPDMPCIDEV)               pPciDev;
     209    /** The PCI device region (high 16-bit word) and subregion (low word),
     210     *  UINT32_MAX if not applicable. */
     211    uint32_t                            iPciRegion;
     212    /** The number of ports covered by this entry. */
     213    RTIOPORT                            cPorts;
     214    /** The current port mapping (duplicates lookup table). */
     215    RTIOPORT                            uPort;
     216    /** The entry of the first statistics entry, UINT16_MAX if no stats. */
     217    uint16_t                            idxStats;
     218    /** Set if mapped, clear if not.
     219     * Only updated when critsect is held exclusively.   */
     220    bool                                fMapped;
     221    /** Same as the handle index. */
     222    uint16_t                            idxSelf;
     223} IOMIOPORTENTRYR3;
     224/** Pointer to a ring-3 I/O port handle table entry. */
     225typedef IOMIOPORTENTRYR3 *PIOMIOPORTENTRYR3;
     226/** Pointer to a const ring-3 I/O port handle table entry. */
     227typedef IOMIOPORTENTRYR3 const *PCIOMIOPORTENTRYR3;
     228
     229/**
     230 * I/O port statistics entry (one I/O port).
     231 */
     232typedef struct IOMIOPORTSTATSENTRY
     233{
     234    /** Number of INs to this port from R3. */
     235    STAMCOUNTER                 InR3;
     236    /** Profiling IN handler overhead in R3. */
     237    STAMPROFILE                 ProfInR3;
     238    /** Number of OUTs to this port from R3. */
     239    STAMCOUNTER                 OutR3;
     240    /** Profiling OUT handler overhead in R3. */
     241    STAMPROFILE                 ProfOutR3;
     242
     243    /** Number of INs to this port from R0/RC. */
     244    STAMCOUNTER                 InRZ;
     245    /** Profiling IN handler overhead in R0/RC. */
     246    STAMPROFILE                 ProfInRZ;
     247    /** Number of INs to this port from R0/RC which was serviced in R3. */
     248    STAMCOUNTER                 InRZToR3;
     249
     250    /** Number of OUTs to this port from R0/RC. */
     251    STAMCOUNTER                 OutRZ;
     252    /** Profiling OUT handler overhead in R0/RC. */
     253    STAMPROFILE                 ProfOutRZ;
     254    /** Number of OUTs to this port from R0/RC which was serviced in R3. */
     255    STAMCOUNTER                 OutRZToR3;
     256} IOMIOPORTSTATSENTRY;
     257/** Pointer to I/O port statistics entry. */
     258typedef IOMIOPORTSTATSENTRY *PIOMIOPORTSTATSENTRY;
    141259
    142260
     
    281399/**
    282400 * The IOM trees.
     401 *
    283402 * These are offset based the nodes and root must be in the same
    284403 * memory block in HC. The locations of IOM structure and the hypervisor heap
     
    306425/** Pointer to the IOM trees. */
    307426typedef IOMTREES *PIOMTREES;
    308 
    309 
    310 /**
    311  * Converts an IOM pointer into a VM pointer.
    312  * @returns Pointer to the VM structure the PGM is part of.
    313  * @param   pIOM   Pointer to IOM instance data.
    314  */
    315 #define IOM2VM(pIOM)  ( (PVM)((char*)pIOM - pIOM->offVM) )
    316 
    317 /**
    318  * IOM Data (part of VM)
    319  */
    320 typedef struct IOM
    321 {
    322     /** Pointer to the trees - R3 ptr. */
    323     R3PTRTYPE(PIOMTREES)            pTreesR3;
    324     /** Pointer to the trees - R0 ptr. */
    325     R0PTRTYPE(PIOMTREES)            pTreesR0;
    326 
    327     /** MMIO physical access handler type.   */
    328     PGMPHYSHANDLERTYPE              hMmioHandlerType;
    329     uint32_t                        u32Padding;
    330 
    331     /** Lock serializing EMT access to IOM. */
    332 #ifdef IOM_WITH_CRIT_SECT_RW
    333     PDMCRITSECTRW                   CritSect;
    334 #else
    335     PDMCRITSECT                     CritSect;
    336 #endif
    337 
    338     /** @name I/O Port statistics.
    339      * @{ */
    340     STAMCOUNTER                     StatInstIn;
    341     STAMCOUNTER                     StatInstOut;
    342     STAMCOUNTER                     StatInstIns;
    343     STAMCOUNTER                     StatInstOuts;
    344     /** @} */
    345 
    346     /** @name MMIO statistics.
    347      * @{ */
    348     STAMPROFILE                     StatRZMMIOHandler;
    349     STAMCOUNTER                     StatRZMMIOFailures;
    350 
    351     STAMPROFILE                     StatRZInstMov;
    352     STAMPROFILE                     StatRZInstCmp;
    353     STAMPROFILE                     StatRZInstAnd;
    354     STAMPROFILE                     StatRZInstOr;
    355     STAMPROFILE                     StatRZInstXor;
    356     STAMPROFILE                     StatRZInstBt;
    357     STAMPROFILE                     StatRZInstTest;
    358     STAMPROFILE                     StatRZInstXchg;
    359     STAMPROFILE                     StatRZInstStos;
    360     STAMPROFILE                     StatRZInstLods;
    361 #ifdef IOM_WITH_MOVS_SUPPORT
    362     STAMPROFILEADV                  StatRZInstMovs;
    363     STAMPROFILE                     StatRZInstMovsToMMIO;
    364     STAMPROFILE                     StatRZInstMovsFromMMIO;
    365     STAMPROFILE                     StatRZInstMovsMMIO;
    366 #endif
    367     STAMCOUNTER                     StatRZInstOther;
    368 
    369     STAMCOUNTER                     StatRZMMIO1Byte;
    370     STAMCOUNTER                     StatRZMMIO2Bytes;
    371     STAMCOUNTER                     StatRZMMIO4Bytes;
    372     STAMCOUNTER                     StatRZMMIO8Bytes;
    373 
    374     STAMCOUNTER                     StatR3MMIOHandler;
    375 
    376     RTUINT                          cMovsMaxBytes;
    377     RTUINT                          cStosMaxBytes;
    378     /** @} */
    379 } IOM;
    380 /** Pointer to IOM instance data. */
    381 typedef IOM *PIOM;
    382427
    383428
     
    433478     * (Saves quite some time in rep outs/ins instruction emulation.)
    434479     * @{ */
     480    /** I/O port registration index for the last read operation. */
     481    uint16_t                            idxIoPortLastRead;
     482    /** I/O port registration index for the last write operation. */
     483    uint16_t                            idxIoPortLastWrite;
     484    /** I/O port registration index for the last read string operation. */
     485    uint16_t                            idxIoPortLastReadStr;
     486    /** I/O port registration index for the last write string operation. */
     487    uint16_t                            idxIoPortLastWriteStr;
     488    uint32_t                            u32Padding;
     489
    435490    R3PTRTYPE(PIOMIOPORTRANGER3)    pRangeLastReadR3;
    436491    R3PTRTYPE(PIOMIOPORTRANGER3)    pRangeLastWriteR3;
     
    450505/** Pointer to IOM per virtual CPU instance data. */
    451506typedef IOMCPU *PIOMCPU;
     507
     508
     509/**
     510 * IOM Data (part of VM)
     511 */
     512typedef struct IOM
     513{
     514    /** Pointer to the trees - R3 ptr. */
     515    R3PTRTYPE(PIOMTREES)            pTreesR3;
     516    /** Pointer to the trees - R0 ptr. */
     517    R0PTRTYPE(PIOMTREES)            pTreesR0;
     518
     519    /** MMIO physical access handler type.   */
     520    PGMPHYSHANDLERTYPE              hMmioHandlerType;
     521    uint32_t                        u32Padding;
     522
     523    /** @name I/O ports
     524     * @note The updating of these variables is done exclusively from EMT(0).
     525     * @{ */
     526    /** Number of I/O port registrations. */
     527    uint32_t                        cIoPortRegs;
     528    /** The size of the paIoPortsRegs allocation (in entries). */
     529    uint32_t                        cIoPortAlloc;
     530    /** I/O port registration table for ring-3.
     531     * There is a parallel table in ring-0, IOMR0PERVM::paIoPortRegs. */
     532    R3PTRTYPE(PIOMIOPORTENTRYR3)    paIoPortRegs;
     533    /** Number of entries in the lookup table. */
     534    uint32_t                        cIoPortLookupEntries;
     535    uint32_t                        u32Padding1;
     536    /** I/O port lookup table. */
     537    R3PTRTYPE(PIOMIOPORTLOOKUPENTRY) paIoPortLookup;
     538
     539    /** The number of valid entries in paioPortStats. */
     540    uint32_t                        cIoPortStats;
     541    /** The size of the paIoPortStats allocation (in entries). */
     542    uint32_t                        cIoPortStatsAllocation;
     543    /** I/O port lookup table.   */
     544    R3PTRTYPE(PIOMIOPORTSTATSENTRY) paIoPortStats;
     545    /** Dummy stats entry so we don't need to check for NULL pointers so much. */
     546    IOMIOPORTSTATSENTRY             IoPortDummyStats;
     547    /** @} */
     548
     549
     550    /** Lock serializing EMT access to IOM. */
     551#ifdef IOM_WITH_CRIT_SECT_RW
     552    PDMCRITSECTRW                   CritSect;
     553#else
     554    PDMCRITSECT                     CritSect;
     555#endif
     556
     557#if 0 /* unused */
     558    /** @name I/O Port statistics.
     559     * @{ */
     560    STAMCOUNTER                     StatInstIn;
     561    STAMCOUNTER                     StatInstOut;
     562    STAMCOUNTER                     StatInstIns;
     563    STAMCOUNTER                     StatInstOuts;
     564    /** @} */
     565#endif
     566
     567    /** @name MMIO statistics.
     568     * @{ */
     569    STAMPROFILE                     StatRZMMIOHandler;
     570    STAMCOUNTER                     StatRZMMIOFailures;
     571
     572    STAMPROFILE                     StatRZInstMov;
     573    STAMPROFILE                     StatRZInstCmp;
     574    STAMPROFILE                     StatRZInstAnd;
     575    STAMPROFILE                     StatRZInstOr;
     576    STAMPROFILE                     StatRZInstXor;
     577    STAMPROFILE                     StatRZInstBt;
     578    STAMPROFILE                     StatRZInstTest;
     579    STAMPROFILE                     StatRZInstXchg;
     580    STAMPROFILE                     StatRZInstStos;
     581    STAMPROFILE                     StatRZInstLods;
     582#ifdef IOM_WITH_MOVS_SUPPORT
     583    STAMPROFILEADV                  StatRZInstMovs;
     584    STAMPROFILE                     StatRZInstMovsToMMIO;
     585    STAMPROFILE                     StatRZInstMovsFromMMIO;
     586    STAMPROFILE                     StatRZInstMovsMMIO;
     587#endif
     588    STAMCOUNTER                     StatRZInstOther;
     589
     590    STAMCOUNTER                     StatRZMMIO1Byte;
     591    STAMCOUNTER                     StatRZMMIO2Bytes;
     592    STAMCOUNTER                     StatRZMMIO4Bytes;
     593    STAMCOUNTER                     StatRZMMIO8Bytes;
     594
     595    STAMCOUNTER                     StatR3MMIOHandler;
     596
     597    RTUINT                          cMovsMaxBytes;
     598    RTUINT                          cStosMaxBytes;
     599    /** @} */
     600} IOM;
     601/** Pointer to IOM instance data. */
     602typedef IOM *PIOM;
     603
     604
     605/**
     606 * IOM data kept in the ring-0 GVM.
     607 */
     608typedef struct IOMR0PERVM
     609{
     610    /** @name I/O ports
     611     * @{ */
     612    /** The higest ring-0 I/O port registration plus one. */
     613    uint32_t                        cIoPortMax;
     614    /** The size of the paIoPortsRegs allocation (in entries). */
     615    uint32_t                        cIoPortAlloc;
     616    /** I/O port registration table for ring-0.
     617     * There is a parallel table for ring-3, paIoPortRing3Regs. */
     618    R0PTRTYPE(PIOMIOPORTENTRYR0)    paIoPortRegs;
     619    /** I/O port lookup table. */
     620    R0PTRTYPE(PIOMIOPORTLOOKUPENTRY) paIoPortLookup;
     621    /** I/O port registration table for ring-3.
     622     * Also mapped to ring-3 as IOM::paIoPortRegs. */
     623    R0PTRTYPE(PIOMIOPORTENTRYR3)    paIoPortRing3Regs;
     624    /** Handle to the allocation backing both the ring-0 and ring-3 registration
     625     * tables as well as the lookup table. */
     626    RTR0MEMOBJ                      hIoPortMemObj;
     627    /** Handle to the ring-3 mapping of the lookup and ring-3 registration table. */
     628    RTR0MEMOBJ                      hIoPortMapObj;
     629#ifdef VBOX_WITH_STATISTICS
     630    /** The size of the paIoPortStats allocation (in entries). */
     631    uint32_t                        cIoPortStatsAllocation;
     632    /** I/O port lookup table.   */
     633    R0PTRTYPE(PIOMIOPORTSTATSENTRY) paIoPortStats;
     634    /** Handle to the allocation backing the I/O port statistics. */
     635    RTR0MEMOBJ                      hIoPortStatsMemObj;
     636    /** Handle to the ring-3 mapping of the I/O port statistics. */
     637    RTR0MEMOBJ                      hIoPortStatsMapObj;
     638#endif
     639    /** @} */
     640} IOMR0PERVM;
    452641
    453642
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r80334 r80641  
    5151//# define NEM_WIN_USE_OUR_OWN_RUN_API          /**< Applies to ring-3 code only. Useful for testing VID API. */
    5252# define NEM_WIN_WITH_RING0_RUNLOOP             /**< Enables the ring-0 runloop. */
    53 # define NEM_WIN_USE_RING0_RUNLOOP_BY_DEFAULT   /**< For quickly testing ring-3 API without messing with CFGM. */
     53//# define NEM_WIN_USE_RING0_RUNLOOP_BY_DEFAULT   /**< For quickly testing ring-3 API without messing with CFGM. */
    5454# if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS)
    5555#  error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS"
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