VirtualBox

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


Ignore:
Timestamp:
Apr 16, 2025 10:42:46 AM (3 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168520
Message:

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

File:
1 edited

Legend:

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

    r108976 r108997  
    661661
    662662
    663 static void gicDistReadLpiConfigTableFromMemory(PPDMDEVINS pDevIns, PGICDEV pGicDev)
     663static void gicDistReadLpiConfigTableFromMem(PPDMDEVINS pDevIns, PGICDEV pGicDev)
    664664{
    665665    Assert(pGicDev->fEnableLpis);
    666666    LogFlowFunc(("\n"));
    667667
    668     /* Check if the guest is disabling LPIs by setting GICR_PROPBASER.IDBits < 13. */
     668    /* Check if the guest is disabling LPIs by setting the number of LPI INTID bits below the minimum required bits. */
    669669    uint8_t const cIdBits = RT_BF_GET(pGicDev->uLpiConfigBaseReg.u, GIC_BF_REDIST_REG_PROPBASER_ID_BITS) + 1;
    670670    if (cIdBits < GIC_LPI_ID_BITS_MIN)
     
    680680    int const rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysLpiConfigTable, (void *)&pGicDev->abLpiConfig[0], cbLpiConfigTable);
    681681    AssertRC(rc);
     682}
     683
     684
     685static void gicReDistReadLpiPendingBitmapFromMem(PPDMDEVINS pDevIns, PVMCPU pVCpu, PGICDEV pGicDev)
     686{
     687    Assert(pGicDev->fEnableLpis);
     688    LogFlowFunc(("\n"));
     689
     690    PGICCPU    pGicCpu   = VMCPU_TO_GICCPU(pVCpu);
     691    bool const fIsZeroed = RT_BF_GET(pGicDev->uLpiPendingBaseReg.u, GIC_BF_REDIST_REG_PENDBASER_PTZ);
     692    if (!fIsZeroed)
     693    {
     694        /* Copy the LPI pending bitmap from guest memory to our internal cache. */
     695        RTGCPHYS const GCPhysLpiPendingBitmap = (pGicDev->uLpiPendingBaseReg.u & GIC_BF_REDIST_REG_PENDBASER_PHYS_ADDR_MASK)
     696                                              + GIC_INTID_RANGE_LPI_START;  /* Skip first 1KB (since LPI INTIDs start at 8192). */
     697        uint32_t const cbLpiPendingBitmap     = sizeof(pGicDev->bmLpiPending);
     698
     699        /** @todo Try releasing and re-acquiring the device critical section here.
     700         *        Probably safe, but haven't verified this... */
     701        int const rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysLpiPendingBitmap, (void *)&pGicCpu->bmLpiPending[0],
     702                                             cbLpiPendingBitmap);
     703        AssertRC(rc);
     704    }
     705    else
     706        RT_ZERO(pGicCpu->bmLpiPending); /* Paranoia. */
    682707}
    683708
     
    24822507            break;
    24832508        case GIC_REDIST_REG_CTLR_OFF:
    2484             pGicDev->fEnableLpis = RT_BOOL(uValue & GIC_REDIST_REG_CTLR_ENABLE_LPI);
    2485             if (pGicDev->fEnableLpis)
    2486                 gicDistReadLpiConfigTableFromMemory(pDevIns, pGicDev);
    2487             break;
     2509        {
     2510            /* Check if LPIs are supported and whether the enable LPI bit changed. */
     2511            uint32_t const uOldCtlr = pGicDev->fEnableLpis ? GIC_REDIST_REG_CTLR_ENABLE_LPI : 0;
     2512            uint32_t const uNewCtlr = uValue & GIC_REDIST_REG_CTLR_ENABLE_LPI;
     2513            if (   pGicDev->fLpi
     2514                && ((uNewCtlr ^ uOldCtlr) & GIC_REDIST_REG_CTLR_ENABLE_LPI))
     2515            {
     2516                pGicDev->fEnableLpis = RT_BOOL(uNewCtlr & GIC_REDIST_REG_CTLR_ENABLE_LPI);
     2517                if (pGicDev->fEnableLpis)
     2518                {
     2519                    gicDistReadLpiConfigTableFromMem(pDevIns, pGicDev);
     2520                    gicReDistReadLpiPendingBitmapFromMem(pDevIns, pVCpu, pGicDev);
     2521                }
     2522                else
     2523                {
     2524                    PGICCPU pGicCpu = VMCPU_TO_GICCPU(pVCpu);
     2525                    RT_ZERO(pGicCpu->bmLpiPending);
     2526                }
     2527            }
     2528            break;
     2529        }
    24882530        case GIC_REDIST_REG_PROPBASER_OFF:
    24892531            pGicDev->uLpiConfigBaseReg.s.Lo = uValue & RT_LO_U32(GIC_REDIST_REG_PROPBASER_RW_MASK);
     
    31783220    pGicCpu->fIntrGroup0Enabled = false;
    31793221    pGicCpu->fIntrGroup1Enabled = false;
     3222    RT_ZERO(pGicCpu->bmLpiPending);
    31803223}
    31813224
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