VirtualBox

Changeset 109021 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Apr 18, 2025 8:56:15 AM (3 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168550
Message:

VMM/GIC: bugref:10877 GIC ITS, work-in-progress.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r109003 r109021  
    661661
    662662
    663 static void gicDistReadLpiConfigTableFromMem(PPDMDEVINS pDevIns, PGICDEV pGicDev)
    664 {
     663DECLHIDDEN(void) gicDistReadLpiConfigTableFromMem(PPDMDEVINS pDevIns)
     664{
     665    PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV);
    665666    Assert(pGicDev->fEnableLpis);
    666667    LogFlowFunc(("\n"));
     
    669670    uint8_t const cIdBits = RT_BF_GET(pGicDev->uLpiConfigBaseReg.u, GIC_BF_REDIST_REG_PROPBASER_ID_BITS) + 1;
    670671    if (cIdBits < GIC_LPI_ID_BITS_MIN)
     672    {
     673        RT_ZERO(pGicDev->abLpiConfig);
    671674        return;
     675    }
    672676
    673677    /* Copy the LPI config table from guest memory to our internal cache. */
     
    25172521                if (pGicDev->fEnableLpis)
    25182522                {
    2519                     gicDistReadLpiConfigTableFromMem(pDevIns, pGicDev);
     2523                    gicDistReadLpiConfigTableFromMem(pDevIns);
    25202524                    gicReDistReadLpiPendingBitmapFromMem(pDevIns, pVCpu, pGicDev);
    25212525                }
     
    26682672                    VERR_INVALID_PARAMETER);
    26692673
    2670     int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED);
    2671     PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock);
     2674    GIC_CRIT_SECT_ENTER(pDevIns);
    26722675
    26732676    /* Update the interrupt pending state. */
     
    26802683    STAM_PROFILE_STOP(&pGicCpu->StatProfSetSpi, a);
    26812684
    2682     PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
     2685    GIC_CRIT_SECT_LEAVE(pDevIns);
    26832686    return rc;
    26842687}
     
    27072710                    VERR_INVALID_PARAMETER);
    27082711
    2709     int const  rcLock  = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED);
    2710     PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock);
     2712    GIC_CRIT_SECT_ENTER(pDevIns);
    27112713
    27122714    /* Update the interrupt pending state. */
     
    27192721    STAM_PROFILE_STOP(&pGicCpu->StatProfSetPpi, b);
    27202722
    2721     PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
     2723    GIC_CRIT_SECT_LEAVE(pDevIns);
    27222724    return rc;
    27232725}
     
    27412743    uint32_t const cCpus   = pVM->cCpus;
    27422744    AssertReturn(uIntId <= GIC_INTID_RANGE_SGI_LAST, VERR_INVALID_PARAMETER);
    2743     Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->pCritSectRoR3)); RT_NOREF_PV(pDevIns);
     2745    Assert(GIC_CRIT_SECT_IS_OWNER(pDevIns)); NOREF(pDevIns);
    27442746
    27452747    for (VMCPUID idCpu = 0; idCpu < cCpus; idCpu++)
     
    28452847    PGICDEV    pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV);
    28462848
    2847     int const  rcLock  = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED);
    2848     PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock);
     2849    GIC_CRIT_SECT_ENTER(pDevIns);
    28492850
    28502851    switch (u32Reg)
     
    29482949    }
    29492950
    2950     PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
     2951    GIC_CRIT_SECT_LEAVE(pDevIns);
    29512952
    29522953    LogFlowFunc(("pVCpu=%p u32Reg=%#x{%s} pu64Value=%RX64\n", pVCpu, u32Reg, gicIccGetRegDescription(u32Reg), *pu64Value));
     
    29722973    PGICCPU    pGicCpu = VMCPU_TO_GICCPU(pVCpu);
    29732974
    2974     int const  rcLock  = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED);
    2975     PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock);
     2975    GIC_CRIT_SECT_ENTER(pDevIns);
    29762976
    29772977    VBOXSTRICTRC rcStrict = VINF_SUCCESS;
     
    31383138    }
    31393139
    3140     PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
     3140    GIC_CRIT_SECT_LEAVE(pDevIns);
    31413141    return rcStrict;
    31423142}
  • trunk/src/VBox/VMM/VMMAll/GITSAll.cpp

    r109011 r109021  
    3131*********************************************************************************************************************************/
    3232#define LOG_GROUP LOG_GROUP_DEV_GIC
    33 #include "GITSInternal.h"
     33#include "GICInternal.h"
    3434
    3535#include <VBox/log.h>
     
    5050/** Gets whether the given register offset is within the specified range. */
    5151#define GITS_IS_REG_IN_RANGE(a_offReg, a_offFirst, a_cbRegion)    ((uint32_t)(a_offReg) - (a_offFirst) < (a_cbRegion))
    52 
    53 /** Acquire the device critical section. */
    54 #define GITS_CRIT_SECT_ENTER(a_pDevIns) \
    55     do \
    56     { \
    57         int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS); \
    58         PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); \
    59     } while(0)
    60 
    61 /** Release the device critical section. */
    62 #define GITS_CRIT_SECT_LEAVE(a_pDevIns)             PDMDevHlpCritSectLeave((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo))
    63 
    64 /** Returns whether the critical section is held. */
    65 #define GITS_CRIT_SECT_IS_OWNER(a_pDevIns)          PDMDevHlpCritSectIsOwner((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo))
    6652
    6753/** GITS diagnostic enum description expansion.
     
    137123    GITSDIAG_DESC(CmdQueue_Basic_Unknown_Cmd),
    138124    GITSDIAG_DESC(CmdQueue_Basic_Invalid_PhysAddr),
     125    GITSDIAG_DESC(CmdQueue_Cmd_Invall_Icid_Overflow),
    139126    GITSDIAG_DESC(CmdQueue_Cmd_Mapc_Icid_Overflow),
    140127    /* kGitsDiag_End */
     
    252239    Log4Func(("enmDiag=%#RX32 (%s) fStallQueue=%RTbool\n", enmDiag, gitsGetDiagDescription(enmDiag)));
    253240
    254     GITS_CRIT_SECT_ENTER(pDevIns);
     241    GIC_CRIT_SECT_ENTER(pDevIns);
    255242
    256243    /* Record the error and stall the queue. */
     
    260247        pGitsDev->uCmdReadReg |= GITS_BF_CTRL_REG_CREADR_STALLED_MASK;
    261248
    262     GITS_CRIT_SECT_LEAVE(pDevIns);
     249    GIC_CRIT_SECT_LEAVE(pDevIns);
    263250
    264251    /* Since we don't support SEIs, so there should be nothing more to do here. */
     
    296283{
    297284    Log4Func(("\n"));
    298     Assert(GITS_CRIT_SECT_IS_OWNER(pDevIns));
     285    Assert(GIC_CRIT_SECT_IS_OWNER(pDevIns));
    299286    if (    gitsCmdQueueCanProcessRequests(pGitsDev)
    300287        && !gitsCmdQueueIsEmpty(pGitsDev))
     
    547534        static uint32_t const s_acbPageSize[] = { _4K, _16K, _64K, _64K };
    548535        static const char* const s_apszType[] = { "UnImpl", "Devices", "vPEs", "Intr Collections" };
    549 
    550         uint64_t const uReg        = pGitsDev->aItsTableRegs[i].u;
    551         uint16_t const uSize       = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_SIZE);
    552         uint16_t const cPages      = uSize > 0 ? uSize + 1 : 0;
    553         uint8_t const  idxPageSize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_PAGESIZE);
    554         uint64_t const cbItsTable  = cPages * s_acbPageSize[idxPageSize];
    555         uint8_t const  uEntrySize  = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_ENTRY_SIZE);
    556         uint8_t const  idxType     = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_TYPE);
    557         const char *pszType        = s_apszType[idxType];
    558         pHlp->pfnPrintf(pHlp, "  GITS_BASER[%u]      = %#RX64\n", i, uReg);
    559         pHlp->pfnPrintf(pHlp, "    Size               = %#x (pages=%u total=%.Rhcb)\n", uSize, cPages, cbItsTable);
    560         pHlp->pfnPrintf(pHlp, "    Page size          = %#x (%.Rhcb)\n", idxPageSize, s_acbPageSize[idxPageSize]);
    561         pHlp->pfnPrintf(pHlp, "    Shareability       = %#x\n",      RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_SHAREABILITY));
    562         pHlp->pfnPrintf(pHlp, "    Phys addr          = %#RX64 (addr=%#RX64)\n", uReg & GITS_BF_CTRL_REG_BASER_PHYS_ADDR_MASK,
    563                                                                                  gitsGetBaseRegPhysAddr(uReg));
    564         pHlp->pfnPrintf(pHlp, "    Entry size         = %#x (%u bytes)\n", uEntrySize, uEntrySize > 0 ? uEntrySize + 1 : 0);
    565         pHlp->pfnPrintf(pHlp, "    Outer cache        = %#x\n",      RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_OUTER_CACHE));
    566         pHlp->pfnPrintf(pHlp, "    Type               = %#x (%s)\n", idxType, pszType);
    567         pHlp->pfnPrintf(pHlp, "    Inner cache        = %#x\n",      RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_INNER_CACHE));
    568         pHlp->pfnPrintf(pHlp, "    Indirect           = %RTbool\n",  RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_INDIRECT)));
    569         pHlp->pfnPrintf(pHlp, "    Valid              = %RTbool\n",  RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_VALID)));
     536        uint64_t const uReg    = pGitsDev->aItsTableRegs[i].u;
     537        bool const     fValid  = RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_VALID));
     538        uint8_t const  idxType = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_TYPE);
     539        if (   fValid
     540            || idxType != GITS_BASER_TYPE_UNIMPL)
     541        {
     542            uint16_t const uSize       = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_SIZE);
     543            uint16_t const cPages      = uSize > 0 ? uSize + 1 : 0;
     544            uint8_t const  idxPageSize = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_PAGESIZE);
     545            uint64_t const cbItsTable  = cPages * s_acbPageSize[idxPageSize];
     546            uint8_t const  uEntrySize  = RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_ENTRY_SIZE);
     547            bool const     fIndirect   = RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_INDIRECT));
     548            const char *pszType        = s_apszType[idxType];
     549            pHlp->pfnPrintf(pHlp, "  GITS_BASER[%u]      = %#RX64\n", i, uReg);
     550            pHlp->pfnPrintf(pHlp, "    Size               = %#x (pages=%u total=%.Rhcb)\n", uSize, cPages, cbItsTable);
     551            pHlp->pfnPrintf(pHlp, "    Page size          = %#x (%.Rhcb)\n", idxPageSize, s_acbPageSize[idxPageSize]);
     552            pHlp->pfnPrintf(pHlp, "    Shareability       = %#x\n",      RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_SHAREABILITY));
     553            pHlp->pfnPrintf(pHlp, "    Phys addr          = %#RX64 (addr=%#RX64)\n", uReg & GITS_BF_CTRL_REG_BASER_PHYS_ADDR_MASK,
     554                                                                                     gitsGetBaseRegPhysAddr(uReg));
     555            pHlp->pfnPrintf(pHlp, "    Entry size         = %#x (%u bytes)\n", uEntrySize, uEntrySize > 0 ? uEntrySize + 1 : 0);
     556            pHlp->pfnPrintf(pHlp, "    Outer cache        = %#x\n",      RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_OUTER_CACHE));
     557            pHlp->pfnPrintf(pHlp, "    Type               = %#x (%s)\n", idxType, pszType);
     558            pHlp->pfnPrintf(pHlp, "    Inner cache        = %#x\n",      RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_INNER_CACHE));
     559            pHlp->pfnPrintf(pHlp, "    Indirect           = %RTbool\n",  fIndirect);
     560            pHlp->pfnPrintf(pHlp, "    Valid              = %RTbool\n",  fValid);
     561        }
    570562    }
    571563
     
    573565    {
    574566        uint64_t const uReg   = pGitsDev->uCmdBaseReg.u;
    575         uint8_t const uSize   = RT_BF_GET(uReg, GITS_BF_CTRL_REG_CBASER_SIZE);
     567        uint8_t const  uSize  = RT_BF_GET(uReg, GITS_BF_CTRL_REG_CBASER_SIZE);
    576568        uint16_t const cPages = uSize > 0 ? uSize + 1 : 0;
    577569        pHlp->pfnPrintf(pHlp, "  GITS_CBASER        = %#RX64\n", uReg);
     
    624616
    625617    /* Hold the critical section as we could be accessing the device state simultaneously with MMIO accesses. */
    626     GITS_CRIT_SECT_ENTER(pDevIns);
     618    GIC_CRIT_SECT_ENTER(pDevIns);
    627619
    628620    if (gitsCmdQueueCanProcessRequests(pGitsDev))
     
    645637
    646638            /* Leave the critical section while reading (a potentially large number of) commands from guest memory. */
    647             GITS_CRIT_SECT_LEAVE(pDevIns);
     639            GIC_CRIT_SECT_LEAVE(pDevIns);
    648640
    649641            if (offWrite > offRead)
     
    673665            {
    674666                /* Indicate to the guest we've fetched all commands. */
    675                 GITS_CRIT_SECT_ENTER(pDevIns);
     667                GIC_CRIT_SECT_ENTER(pDevIns);
    676668                pGitsDev->uCmdReadReg   = offWrite;
    677669                pGitsDev->uCmdWriteReg &= ~GITS_BF_CTRL_REG_CWRITER_RETRY_MASK;
    678670
    679671                /* Don't hold the critical section while processing commands. */
    680                 GITS_CRIT_SECT_LEAVE(pDevIns);
     672                GIC_CRIT_SECT_LEAVE(pDevIns);
    681673
    682674                uint32_t const cCmds = cbCmds / sizeof(GITSCMD);
     
    689681                        case GITS_CMD_ID_MAPC:
    690682                        {
     683                            /* Map interrupt collection with a target CPU ID. */
    691684                            uint64_t const uDw2 = pCmd->au64[2].u;
    692685                            uint8_t  const fValid            = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_VALID);
     
    696689                            if (RT_LIKELY(uIntrCollectionId < RT_ELEMENTS(pGitsDev->auCtes)))
    697690                            {
    698                                 GITS_CRIT_SECT_ENTER(pDevIns);
     691                                GIC_CRIT_SECT_ENTER(pDevIns);
    699692                                Assert(!RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_PTA));
    700693                                pGitsDev->auCtes[uIntrCollectionId] = RT_BF_MAKE(GITS_BF_CTE_VALID,  fValid)
    701694                                                                    | RT_BF_MAKE(GITS_BF_CTE_RDBASE, uTargetCpuId);
    702                                 GITS_CRIT_SECT_LEAVE(pDevIns);
     695                                GIC_CRIT_SECT_LEAVE(pDevIns);
    703696                            }
    704697                            else
     
    711704                        case GITS_CMD_ID_SYNC:
    712705                            /* Nothing to do since all previous commands have committed their changes to device state. */
     706                            STAM_COUNTER_INC(&pGitsDev->StatCmdSync);
     707                            break;
     708
     709                        case GITS_CMD_ID_INVALL:
     710                        {
     711                            /* Reading the table is likely to take the same time as reading just one entry. */
     712                            uint64_t const uDw2 = pCmd->au64[2].u;
     713                            uint16_t const uIntrCollectionId = RT_BF_GET(uDw2, GITS_BF_CMD_INVALL_DW2_IC_ID);
     714                            if (RT_LIKELY(uIntrCollectionId < RT_ELEMENTS(pGitsDev->auCtes)))
     715                                gicDistReadLpiConfigTableFromMem(pDevIns);
     716                            else
     717                                gitsCmdQueueSetError(pDevIns, pGitsDev, kGitsDiag_CmdQueue_Cmd_Invall_Icid_Overflow,
     718                                                     false /* fStall */);
    713719                            STAM_COUNTER_INC(&pGitsDev->StatCmdInvall);
    714720                            break;
    715 
    716                         case GITS_CMD_ID_INVALL:
    717                             /* Nothing to do as we currently do not cache interrupt mappings. */
    718                             STAM_COUNTER_INC(&pGitsDev->StatCmdSync);
    719                             break;
     721                        }
    720722
    721723                        default:
     
    738740    }
    739741
    740     GITS_CRIT_SECT_LEAVE(pDevIns);
     742    GIC_CRIT_SECT_LEAVE(pDevIns);
    741743    return VINF_SUCCESS;
    742744}
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