VirtualBox

Ignore:
Timestamp:
Apr 7, 2025 10:17:36 AM (2 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168315
Message:

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

File:
1 edited

Legend:

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

    r108864 r108865  
    6767AssertCompileSize(GITSITE, 8);
    6868
     69/** GITS diagnostic enum description expansion.
     70 * The below construct ensures typos in the input to this macro are caught
     71 * during compile time. */
     72#define GITSDIAG_DESC(a_Name)        RT_CONCAT(kGitsDiag_, a_Name) < kGitsDiag_End ? RT_STR(a_Name) : "Ignored"
     73/** GITS diagnostics description for members in GITSDIAG. */
     74static const char *const g_apszGitsDiagDesc[] =
     75{
     76    GITSDIAG_DESC(None),
     77    GITSDIAG_DESC(CmdQueue_PhysAddr_Invalid),
     78    /* kGitsDiag_End */
     79};
     80AssertCompile(RT_ELEMENTS(g_apszGitsDiagDesc) == kGitsDiag_End);
     81#undef GITSDIAG_DESC
     82
    6983
    7084/*********************************************************************************************************************************
     
    108122}
    109123
     124static void gitsCmdQueueSetError(PGITSDEV pGitsDev, GITSDIAG enmError, bool fStallQueue)
     125{
     126    /* Record the error and stall the queue. */
     127    pGitsDev->uCmdQueueError = enmError;
     128    if (fStallQueue)
     129        pGitsDev->uCmdReadReg |= GITS_BF_CTRL_REG_CREADR_STALLED_MASK;
     130
     131    /* Since we don't support SEIs, so there should be nothing more to do here. */
     132    Assert(!RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_SEIS));
     133}
     134
    110135
    111136DECL_FORCE_INLINE(bool) gitsCmdQueueIsEmptyEx(PCGITSDEV pGitsDev, uint32_t *poffRead, uint32_t *poffWrite)
     
    117142
    118143
    119 DECL_HIDDEN_CALLBACK(bool) gitsCmdQueueIsEmpty(PCGITSDEV pGitsDev)
     144DECL_FORCE_INLINE(bool) gitsCmdQueueIsEmpty(PCGITSDEV pGitsDev)
    120145{
    121146    uint32_t offRead;
     
    125150
    126151
    127 DECL_HIDDEN_CALLBACK(bool) gitsCmdQueueCanProcessRequests(PCGITSDEV pGitsDev)
    128 {
    129     if (     pGitsDev->fEnabled
     152DECL_FORCE_INLINE(bool) gitsCmdQueueCanProcessRequests(PCGITSDEV pGitsDev)
     153{
     154    if (    (pGitsDev->uTypeReg.u    & GITS_BF_CTRL_REG_CTLR_ENABLED_MASK)
    130155        &&  (pGitsDev->uCmdBaseReg.u & GITS_BF_CTRL_REG_CBASER_VALID_MASK)
    131156        && !(pGitsDev->uCmdReadReg   & GITS_BF_CTRL_REG_CREADR_STALLED_MASK))
     
    169194        case GITS_CTRL_REG_CTLR_OFF:
    170195            Assert(cb == 4);
    171             uReg = RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_ENABLED,   pGitsDev->fEnabled)
    172                  | RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_QUIESCENT, pGitsDev->fQuiescent);
     196            uReg = pGitsDev->uCtrlReg;
    173197            break;
    174198
     
    193217        case GITS_CTRL_REG_TYPER_OFF + 4:
    194218        {
    195             uint64_t const uVal = RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PHYSICAL,  1)      /* Physical LPIs supported. */
    196                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VIRTUAL,   0) */   /* Virtual LPIs not supported. */
    197                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CCT,       0)      /* Collections in memory not supported. */
    198                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ITT_ENTRY_SIZE, sizeof(GITSITE)) /* ITE size in bytes. */
    199                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ID_BITS,   31)     /* 32-bit event IDs. */
    200                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_DEV_BITS,  31)     /* 32-bit device IDs. */
    201                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SEIS,      0) */   /** @todo SEI support. */
    202                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PTA,       0) */   /* Target is VCPU ID not address. */
    203                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_HCC,       255)    /* Collection count. */
    204                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CID_BITS,  0) */   /* CIL specifies collection ID size. */
    205                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CIL,       0) */   /* 16-bit collection IDs. */
    206                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMOVP,     0) */   /* VMOVP not supported. */
    207                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_MPAM,      0) */   /* MPAM no supported. */
    208                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VSGI,      0) */   /* VSGI not supported. */
    209                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMAPP,     0) */   /* VMAPP not supported. */
    210                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SVPET,     0) */   /* SVPET not supported. */
    211                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_NID,       0) */   /* NID (doorbell) not supported. */
    212                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI,      0) */   /** @todo Reporting receipt of unmapped MSIs. */
    213                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI_IRQ,  0) */   /** @todo Generating interrupt on unmapped MSI. */
    214                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_INV,       1);     /* ITS caches invalidated when clearing
    215                                                                                           GITS_CTLR.Enabled and GITS_BASER<n>.Valid. */
    216             uReg = uVal >> ((offReg & 7) << 3 /* to bits */);
     219            uReg = pGitsDev->uTypeReg.u >> ((offReg & 7) << 3 /* to bits */);
    217220            break;
    218221        }
     
    289292        case GITS_CTRL_REG_CTLR_OFF:
    290293            Assert(cb == 4);
    291             pGitsDev->fEnabled = RT_BF_GET(uValue, GITS_BF_CTRL_REG_CTLR_ENABLED);
     294            Assert(!(pGitsDev->uTypeReg.u & GITS_BF_CTRL_REG_TYPER_UMSI_IRQ_MASK));
     295            pGitsDev->uCtrlReg = uValue & GITS_BF_CTRL_REG_CTLR_RW_MASK;
    292296            gitsCmdQueueThreadWakeUpIfNeeded(pDevIns, pGitsDev);
    293297            break;
     
    340344{
    341345    Log4Func(("\n"));
    342     pGitsDev->fEnabled           = false;
    343     pGitsDev->fUnmappedMsiReport = false;
    344     pGitsDev->fQuiescent         = true;
     346
     347    pGitsDev->uCtrlReg   = RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_QUIESCENT, 1);
     348    pGitsDev->uTypeReg.u = RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PHYSICAL,  1)     /* Physical LPIs supported. */
     349                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VIRTUAL,   0) */  /* Virtual LPIs not supported. */
     350                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CCT,       0)     /* Collections in memory not supported. */
     351                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ITT_ENTRY_SIZE, sizeof(GITSITE)) /* ITE size in bytes. */
     352                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ID_BITS,   31)    /* 32-bit event IDs. */
     353                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_DEV_BITS,  31)    /* 32-bit device IDs. */
     354                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SEIS,      0) */  /* Locally generated errors not recommended. */
     355                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PTA,       0) */  /* Target is VCPU ID not address. */
     356                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_HCC,       255)   /* Collection count. */
     357                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CID_BITS,  0) */  /* CIL specifies collection ID size. */
     358                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CIL,       0) */  /* 16-bit collection IDs. */
     359                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMOVP,     0) */  /* VMOVP not supported. */
     360                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_MPAM,      0) */  /* MPAM no supported. */
     361                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VSGI,      0) */  /* VSGI not supported. */
     362                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMAPP,     0) */  /* VMAPP not supported. */
     363                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SVPET,     0) */  /* SVPET not supported. */
     364                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_NID,       0) */  /* NID (doorbell) not supported. */
     365                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI,      0) */  /** @todo Reporting receipt of unmapped MSIs. */
     366                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI_IRQ,  0) */  /** @todo Generating interrupt on unmapped MSI. */
     367                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_INV,       1);    /* ITS caches invalidated when clearing
     368                                                                                  GITS_CTLR.Enabled and GITS_BASER<n>.Valid. */
    345369    RT_ZERO(pGitsDev->aItsTableRegs);
    346370    pGitsDev->uCmdBaseReg.u      = 0;
     
    356380
    357381    pHlp->pfnPrintf(pHlp, "GIC ITS:\n");
    358     pHlp->pfnPrintf(pHlp, "  uArchRev           = %u\n",      pGitsDev->uArchRev);
    359     pHlp->pfnPrintf(pHlp, "  fEnabled           = %RTbool\n", pGitsDev->fEnabled);
    360     pHlp->pfnPrintf(pHlp, "  fUnmappedMsiReport = %RTbool\n", pGitsDev->fUnmappedMsiReport);
    361     pHlp->pfnPrintf(pHlp, "  fQuiescent         = %RTbool\n", pGitsDev->fQuiescent);
     382
     383    /* Basic info, GITS_CTLR and GITS_TYPER. */
     384    {
     385        GITSDIAG const    enmDiag  = pGitsDev->enmDiag;
     386        const char *const pszDiag  = enmDiag < RT_ELEMENTS(g_apszGitsDiagDesc) ? g_apszGitsDiagDesc[enmDiag] : "(Unknown)";
     387        uint32_t const    uCtrlReg = pGitsDev->uCtrlReg;
     388        pHlp->pfnPrintf(pHlp, "  Error              = %#RX32 (%s)\n", enmDiag, pszDiag);
     389        pHlp->pfnPrintf(pHlp, "  uArchRev           = %u\n",      pGitsDev->uArchRev);
     390        pHlp->pfnPrintf(pHlp, "  uCtrlReg           = %#RX32\n",  uCtrlReg);
     391        pHlp->pfnPrintf(pHlp, "    Enabled            = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_ENABLED));
     392        pHlp->pfnPrintf(pHlp, "    UMSI IRQ           = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_UMSI_IRQ));
     393        pHlp->pfnPrintf(pHlp, "    Quiescent          = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_QUIESCENT));
     394    }
    362395
    363396    /* GITS_BASER<n>. */
     
    420453DECL_HIDDEN_CALLBACK(int) gitsR3CmdQueueProcess(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, void *pvBuf, uint32_t cbBuf)
    421454{
     455    /* Hold the critical section as we could be accessing the device state simultaneously with MMIO accesses. */
    422456    int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS);
    423457    PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock);
     
    434468            AssertRelease(cbCmdQueue <= cbBuf); /** @todo Paranoia; make this a debug assert later. */
    435469
    436 #if 0
    437470            /*
    438              * Allocate space for the command-queue if we haven't done so already.
    439              */
    440             if (pGitsDev->pvCmdQueue != NULL)
    441             {
    442                 if (pGitsDev->cbCmdQueue <= cbCmdQueue)
    443                 {   /* Already allocated sufficient space. */   }
    444                 else
    445                 {
    446                     /* Free old allocation and allocate a new one. */
    447                     RTMemFree(pGitsDev->pvCmdQueue);
    448                     pGitsDev->cbCmdQueue = cbCmdQueue;
    449                     pGitsDev->pvCmdQueue = RTMemAllocZ(cbCmdQueue);
    450                     if (pGitsDev->pvCmdQueue)
    451                     { /* likely */ }
    452                     else
    453                         return VERR_NO_MEMORY;
    454                 }
    455             }
    456             else
    457             {
    458                 /* Allocate one. */
    459                 pGitsDev->cbCmdQueue = cbCmdQueue;
    460                 pGitsDev->pvCmdQueue = RTMemAllocZ(cbCmdQueue);
    461                 if (pGitsDev->pvCmdQueue)
    462                 { /* likely */ }
    463                 else
    464                     return VERR_NO_MEMORY;
    465             }
    466 #endif
    467 
    468             /*
    469              * Read all the commands into the command queue.
     471             * Read all the commands from guest memory into our command queue buffer.
    470472             */
    471473            RTGCPHYS const GCPhysCmds = pGitsDev->uCmdBaseReg.u & GITS_BF_CTRL_REG_CBASER_PHYS_ADDR_MASK;
    472474
    473             /* Leave the critical section before reading (a potentially large amount of) commands. */
     475            /* Temporarily leave the critical section while reading (a potentially large number of) commands from guest memory. */
    474476            PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
    475477
     
    478480            if (offWrite > offRead)
    479481            {
    480                 /* The commands have not wrapped around, read them in one go. */
     482                /* The write offset has not wrapped around, read them in one go. */
    481483                cbCmds = offWrite - offRead;
    482484                Assert(cbCmds <= cbBuf);
     
    485487            else
    486488            {
    487                 /* The commands have wrapped around, read forward and wrapped-around. */
     489                /* The write offset has wrapped around, read till end of buffer followed by wrapped-around data. */
    488490                uint32_t const cbForward = cbCmdQueue - offRead;
    489491                uint32_t const cbWrapped = offWrite;
     
    506508            if (RT_SUCCESS(rc))
    507509            {
    508 
    509510                uint32_t const cCmds = cbCmds / GITS_CMD_SIZE;
    510511                for (uint32_t idxCmd = 0; idxCmd < cCmds; idxCmd++)
     
    519520
    520521            /* Failed to read command queue from the physical address specified by the guest, stall queue and retry later. */
    521 
    522 
    523             /** @todo Stall the command queue. */
     522            gitsCmdQueueSetError(pGitsDev, kGitsDiag_CmdQueue_PhysAddr_Invalid, true /* fStall */);
    524523            return VINF_TRY_AGAIN;
    525524        }
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