VirtualBox

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


Ignore:
Timestamp:
Apr 9, 2025 2:08:25 PM (4 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168405
Message:

VMM/PGMAllGst-armv8.cpp.h: Some work on supporting different granule sizes, bugref:10388

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PGMAllGst-armv8.cpp.h

    r108910 r108920  
    226226
    227227            uPt = pu64Pt[(GCPtr >> 39) & fLookupMask];
    228             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_VALID) { /* probable */ }
     228            if (uPt & ARMV8_VMSA64_DESC_F_VALID) { /* probable */ }
    229229            else return pgmGstWalkReturnNotPresent(pVCpu, pWalk, 0);
    230230
    231             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_TBL_OR_PG) { /* probable */ }
     231            if (uPt & ARMV8_VMSA64_DESC_F_TBL_OR_PG) { /* probable */ }
    232232            else return pgmGstWalkReturnRsvdError(pVCpu, pWalk, 0); /** @todo Only supported if TCR_EL1.DS is set. */
    233233
     
    244244
    245245            uPt = pu64Pt[(GCPtr >> 30) & fLookupMask];
    246             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_VALID) { /* probable */ }
     246            if (uPt & ARMV8_VMSA64_DESC_F_VALID) { /* probable */ }
    247247            else return pgmGstWalkReturnNotPresent(pVCpu, pWalk, 1);
    248248
    249             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_TBL_OR_PG) { /* probable */ }
     249            if (uPt & ARMV8_VMSA64_DESC_F_TBL_OR_PG) { /* probable */ }
    250250            else
    251251            {
     
    270270
    271271            uPt = pu64Pt[(GCPtr >> 21) & fLookupMask];
    272             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_VALID) { /* probable */ }
     272            if (uPt & ARMV8_VMSA64_DESC_F_VALID) { /* probable */ }
    273273            else return pgmGstWalkReturnNotPresent(pVCpu, pWalk, 2);
    274274
    275             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_TBL_OR_PG) { /* probable */ }
     275            if (uPt & ARMV8_VMSA64_DESC_F_TBL_OR_PG) { /* probable */ }
    276276            else
    277277            {
     
    297297
    298298        uPt = pu64Pt[(GCPtr & UINT64_C(0x1ff000)) >> 12];
    299         if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_VALID) { /* probable */ }
     299        if (uPt & ARMV8_VMSA64_DESC_F_VALID) { /* probable */ }
    300300        else return pgmGstWalkReturnNotPresent(pVCpu, pWalk, 3);
    301301
    302         if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_TBL_OR_PG) { /* probable */ }
     302        if (uPt & ARMV8_VMSA64_DESC_F_TBL_OR_PG) { /* probable */ }
    303303        else return pgmGstWalkReturnRsvdError(pVCpu, pWalk, 3); /** No block descriptors. */
    304304
     
    334334    else
    335335    {
     336        /* This also applies to TG1 granule sizes, as both share the same encoding in TCR. */
     337        AssertCompile(ARMV8_TCR_EL1_AARCH64_TG0_INVALID == ARMV8_TCR_EL1_AARCH64_TG1_INVALID);
     338        AssertCompile(ARMV8_TCR_EL1_AARCH64_TG0_16KB    == ARMV8_TCR_EL1_AARCH64_TG1_16KB);
     339        AssertCompile(ARMV8_TCR_EL1_AARCH64_TG0_4KB     == ARMV8_TCR_EL1_AARCH64_TG1_4KB);
     340        AssertCompile(ARMV8_TCR_EL1_AARCH64_TG0_64KB    == ARMV8_TCR_EL1_AARCH64_TG1_64KB);
     341
     342        uint64_t fLookupMaskFull;
     343        RTGCPTR  offPageMask;
     344
     345        RTGCPTR offLvl1BlockMask;
     346        RTGCPTR offLvl2BlockMask;
     347
     348        uint64_t fNextTableOrPageMask;
     349        uint8_t  cLvl0Shift;
     350        uint8_t  cLvl1Shift;
     351        uint8_t  cLvl2Shift;
     352        uint8_t  cLvl3Shift;
     353
     354        RTGCPHYS fGCPhysLvl1BlockBase;
     355        RTGCPHYS fGCPhysLvl2BlockBase;
     356
     357        /** @todo This needs to go into defines in armv8.h if final. */
     358        if RT_CONSTEXPR_IF(a_GranuleSz == ARMV8_TCR_EL1_AARCH64_TG0_4KB)
     359        {
     360            fLookupMaskFull      = RT_BIT_64(9) - 1;
     361            offLvl1BlockMask     = (RTGCPTR)(_1G - 1);
     362            offLvl2BlockMask     = (RTGCPTR)(_2M - 1);
     363            offPageMask          = (RTGCPTR)(_4K - 1);
     364            fNextTableOrPageMask = UINT64_C(0xfffffffff000);
     365            cLvl0Shift           = 39;
     366            cLvl1Shift           = 30;
     367            cLvl2Shift           = 21;
     368            cLvl3Shift           = 12;
     369            fGCPhysLvl1BlockBase = UINT64_C(0xffffc0000000);
     370            fGCPhysLvl2BlockBase = UINT64_C(0xffffffe00000);
     371        }
     372        else if RT_CONSTEXPR_IF(a_GranuleSz == ARMV8_TCR_EL1_AARCH64_TG0_16KB)
     373        {
     374            fLookupMaskFull      = RT_BIT_64(11) - 1;
     375            offLvl1BlockMask     = 0; /** @todo TCR_EL1.DS support. */
     376            offLvl2BlockMask     = (RTGCPTR)(_32M - 1);
     377            offPageMask          = (RTGCPTR)(_16K - 1);
     378            fNextTableOrPageMask = UINT64_C(0xffffffffc000);
     379            cLvl0Shift           = 47;
     380            cLvl1Shift           = 36;
     381            cLvl2Shift           = 25;
     382            cLvl3Shift           = 14;
     383            fGCPhysLvl1BlockBase = 0; /* Not supported. */
     384            fGCPhysLvl2BlockBase = UINT64_C(0xfffffe000000);
     385        }
     386        else if RT_CONSTEXPR_IF(a_GranuleSz == ARMV8_TCR_EL1_AARCH64_TG0_64KB)
     387        {
     388            Assert(a_InitialLookupLvl > 0);
     389
     390            fLookupMaskFull      = RT_BIT_64(13)   - 1;
     391            offLvl1BlockMask     = 0; /** @todo FEAT_LPA (RTGCPTR)(4*_1T - 1) */
     392            offLvl2BlockMask     = (RTGCPTR)(_512M - 1);
     393            offPageMask          = (RTGCPTR)(_64K  - 1);
     394            fNextTableOrPageMask = UINT64_C(0xffffffff0000);
     395            cLvl0Shift           = 0; /* No Level 0 with 64KiB granules. */
     396            cLvl1Shift           = 42;
     397            cLvl2Shift           = 29;
     398            cLvl3Shift           = 16;
     399            fGCPhysLvl1BlockBase = 0; /* Not supported. */
     400            fGCPhysLvl2BlockBase = UINT64_C(0xffffe0000000);
     401        }
     402        else
     403            AssertReleaseFailedReturn(VERR_PGM_MODE_IPE);
     404
     405        /* Get the initial lookup mask. */
    336406        uint8_t const bEl = CPUMGetGuestEL(pVCpu);
    337 
    338407        uint64_t fLookupMask;
    339408        if RT_CONSTEXPR_IF(a_fTtbr0 == true)
     
    342411            fLookupMask = pVCpu->pgm.s.afLookupMaskTtbr1[bEl];
    343412
    344         RTGCPHYS GCPhysPt = CPUMGetEffectiveTtbr(pVCpu, GCPtr);
    345         uint64_t *pu64Pt = NULL;
    346         uint64_t uPt;
     413        RTGCPHYS         GCPhysPt = CPUMGetEffectiveTtbr(pVCpu, GCPtr);
     414        PARMV8VMSA64DESC paDesc  = NULL;
     415        ARMV8VMSA64DESC  Desc;
    347416        int rc;
    348417        if RT_CONSTEXPR_IF(a_InitialLookupLvl == 0)
    349418        {
    350             rc = pgmPhysGCPhys2CCPtrLockless(pVCpu, GCPhysPt, (void **)&pu64Pt);
     419            Assert(cLvl0Shift != 0);
     420            uint8_t const uLvl = 0;
     421
     422            rc = pgmPhysGCPhys2CCPtrLockless(pVCpu, GCPhysPt, (void **)&paDesc);
    351423            if (RT_SUCCESS(rc)) { /* probable */ }
    352             else return pgmGstWalkFastReturnBadPhysAddr(pVCpu, pWalk, 0, rc);
    353 
    354             uPt = pu64Pt[(GCPtr >> 39) & fLookupMask];
    355             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_VALID) { /* probable */ }
    356             else return pgmGstWalkFastReturnNotPresent(pVCpu, pWalk, 0);
    357 
    358             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_TBL_OR_PG) { /* probable */ }
    359             else return pgmGstWalkFastReturnRsvdError(pVCpu, pWalk, 0); /** @todo Only supported if TCR_EL1.DS is set. */
    360 
    361             /* All nine bits from now on. */
    362             fLookupMask = RT_BIT_64(9) - 1;
    363             GCPhysPt = (RTGCPHYS)(uPt & UINT64_C(0xfffffffff000));
     424            else return pgmGstWalkFastReturnBadPhysAddr(pVCpu, pWalk, uLvl, rc);
     425
     426            Desc = ASMAtomicUoReadU64(&paDesc[(GCPtr >> cLvl0Shift) & fLookupMask]);
     427            if (Desc & ARMV8_VMSA64_DESC_F_VALID) { /* probable */ }
     428            else return pgmGstWalkFastReturnNotPresent(pVCpu, pWalk, uLvl);
     429
     430            if (Desc & ARMV8_VMSA64_DESC_F_TBL_OR_PG) { /* probable */ }
     431            else return pgmGstWalkFastReturnRsvdError(pVCpu, pWalk, uLvl); /** @todo Only supported if TCR_EL1.DS is set. */
     432
     433            /* Full lookup mask from now on. */
     434            fLookupMask = fLookupMaskFull;
     435            GCPhysPt = (RTGCPHYS)(Desc & fNextTableOrPageMask);
    364436        }
    365437
    366438        if RT_CONSTEXPR_IF(a_InitialLookupLvl <= 1)
    367439        {
    368             rc = pgmPhysGCPhys2CCPtrLockless(pVCpu, GCPhysPt, (void **)&pu64Pt);
     440            uint8_t const uLvl = 1;
     441
     442            rc = pgmPhysGCPhys2CCPtrLockless(pVCpu, GCPhysPt, (void **)&paDesc);
    369443            if (RT_SUCCESS(rc)) { /* probable */ }
    370             else return pgmGstWalkFastReturnBadPhysAddr(pVCpu, pWalk, 1, rc);
    371 
    372             uPt = pu64Pt[(GCPtr >> 30) & fLookupMask];
    373             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_VALID) { /* probable */ }
    374             else return pgmGstWalkFastReturnNotPresent(pVCpu, pWalk, 1);
    375 
    376             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_TBL_OR_PG) { /* probable */ }
     444            else return pgmGstWalkFastReturnBadPhysAddr(pVCpu, pWalk, uLvl, rc);
     445
     446            Desc = ASMAtomicUoReadU64(&paDesc[(GCPtr >> cLvl1Shift) & fLookupMask]);
     447            if (Desc & ARMV8_VMSA64_DESC_F_VALID) { /* probable */ }
     448            else return pgmGstWalkFastReturnNotPresent(pVCpu, pWalk, uLvl);
     449
     450            if (Desc & ARMV8_VMSA64_DESC_F_TBL_OR_PG) { /* probable */ }
    377451            else
    378452            {
    379                 /* Block descriptor (1G page). */
    380                 pWalk->GCPtr       = GCPtr;
    381                 pWalk->fInfo       = PGM_WALKINFO_SUCCEEDED | PGM_WALKINFO_GIGANTIC_PAGE;
    382                 pWalk->GCPhys      = (RTGCPHYS)(uPt & UINT64_C(0xffffc0000000)) | (GCPtr & (RTGCPTR)(_1G - 1));
     453                if (offLvl1BlockMask != 0)
     454                {
     455                    /* Block descriptor. */
     456                    pWalk->GCPtr       = GCPtr;
     457                    pWalk->fInfo       = PGM_WALKINFO_SUCCEEDED | PGM_WALKINFO_GIGANTIC_PAGE;
     458                    pWalk->GCPhys      = (RTGCPHYS)(Desc & fGCPhysLvl1BlockBase) | (GCPtr & offLvl1BlockMask);
     459                    return VINF_SUCCESS;
     460                }
     461                else
     462                    return pgmGstWalkFastReturnRsvdError(pVCpu, pWalk, uLvl);
     463            }
     464
     465            /* Full lookup mask from now on. */
     466            fLookupMask = fLookupMaskFull;
     467            GCPhysPt = (RTGCPHYS)(Desc & fNextTableOrPageMask);
     468        }
     469
     470        if RT_CONSTEXPR_IF(a_InitialLookupLvl <= 2)
     471        {
     472            uint8_t const uLvl = 2;
     473
     474            rc = pgmPhysGCPhys2CCPtrLockless(pVCpu, GCPhysPt, (void **)&paDesc);
     475            if (RT_SUCCESS(rc)) { /* probable */ }
     476            else return pgmGstWalkFastReturnBadPhysAddr(pVCpu, pWalk, uLvl, rc);
     477
     478            Desc = ASMAtomicUoReadU64(&paDesc[(GCPtr >> cLvl2Shift) & fLookupMask]);
     479            if (Desc & ARMV8_VMSA64_DESC_F_VALID) { /* probable */ }
     480            else return pgmGstWalkFastReturnNotPresent(pVCpu, pWalk, uLvl);
     481
     482            if (Desc & ARMV8_VMSA64_DESC_F_TBL_OR_PG) { /* probable */ }
     483            else
     484            {
     485                /* Block descriptor. */
     486                pWalk->GCPtr      = GCPtr;
     487                pWalk->fInfo      = PGM_WALKINFO_SUCCEEDED | PGM_WALKINFO_BIG_PAGE;
     488                pWalk->GCPhys     = (RTGCPHYS)(Desc & fGCPhysLvl2BlockBase) | (GCPtr & offLvl2BlockMask);
    383489                return VINF_SUCCESS;
    384490            }
    385491
    386             /* All nine bits from now on. */
    387             fLookupMask = RT_BIT_64(9) - 1;
    388             GCPhysPt = (RTGCPHYS)(uPt & UINT64_C(0xfffffffff000));
    389         }
    390 
    391         if RT_CONSTEXPR_IF(a_InitialLookupLvl <= 2)
    392         {
    393             rc = pgmPhysGCPhys2CCPtrLockless(pVCpu, GCPhysPt, (void **)&pu64Pt);
    394             if (RT_SUCCESS(rc)) { /* probable */ }
    395             else return pgmGstWalkFastReturnBadPhysAddr(pVCpu, pWalk, 2, rc);
    396 
    397             uPt = pu64Pt[(GCPtr >> 21) & fLookupMask];
    398             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_VALID) { /* probable */ }
    399             else return pgmGstWalkFastReturnNotPresent(pVCpu, pWalk, 2);
    400 
    401             if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_TBL_OR_PG) { /* probable */ }
    402             else
    403             {
    404                 /* Block descriptor (2M page). */
    405                 pWalk->GCPtr      = GCPtr;
    406                 pWalk->fInfo      = PGM_WALKINFO_SUCCEEDED | PGM_WALKINFO_BIG_PAGE;
    407                 pWalk->GCPhys     = (RTGCPHYS)(uPt & UINT64_C(0xffffffe00000)) | (GCPtr & (RTGCPTR)(_2M - 1));
    408                 return VINF_SUCCESS;
    409             }
    410 
    411             /* All nine bits from now on. */
    412             fLookupMask = RT_BIT_64(9) - 1;
    413             GCPhysPt = (RTGCPHYS)(uPt & UINT64_C(0xfffffffff000));
     492            /* Full lookup mask from now on. */
     493            fLookupMask = fLookupMaskFull;
     494            GCPhysPt = (RTGCPHYS)(Desc & fNextTableOrPageMask);
    414495        }
    415496
    416497        AssertCompile(a_InitialLookupLvl <= 3);
     498        uint8_t const uLvl = 3;
    417499
    418500        /* Next level. */
    419         rc = pgmPhysGCPhys2CCPtrLockless(pVCpu, GCPhysPt, (void **)&pu64Pt);
     501        rc = pgmPhysGCPhys2CCPtrLockless(pVCpu, GCPhysPt, (void **)&paDesc);
    420502        if (RT_SUCCESS(rc)) { /* probable */ }
    421         else return pgmGstWalkFastReturnBadPhysAddr(pVCpu, pWalk, 3, rc);
    422 
    423         uPt = pu64Pt[(GCPtr & UINT64_C(0x1ff000)) >> 12];
    424         if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_VALID) { /* probable */ }
    425         else return pgmGstWalkFastReturnNotPresent(pVCpu, pWalk, 3);
    426 
    427         if (uPt & ARMV8_VMSA64_TBL_ENTRY_F_TBL_OR_PG) { /* probable */ }
    428         else return pgmGstWalkFastReturnRsvdError(pVCpu, pWalk, 3); /** No block descriptors. */
     503        else return pgmGstWalkFastReturnBadPhysAddr(pVCpu, pWalk, uLvl, rc);
     504
     505        Desc = ASMAtomicUoReadU64(&paDesc[(GCPtr >> cLvl3Shift) & fLookupMask]);
     506        if (Desc & ARMV8_VMSA64_DESC_F_VALID) { /* probable */ }
     507        else return pgmGstWalkFastReturnNotPresent(pVCpu, pWalk, uLvl);
     508
     509        if (Desc & ARMV8_VMSA64_DESC_F_TBL_OR_PG) { /* probable */ }
     510        else return pgmGstWalkFastReturnRsvdError(pVCpu, pWalk, uLvl); /* No block descriptors. */
    429511
    430512        pWalk->GCPtr  = GCPtr;
    431513        pWalk->fInfo  = PGM_WALKINFO_SUCCEEDED;
    432         pWalk->GCPhys = (RTGCPHYS)(uPt & UINT64_C(0xfffffffff000)) | (GCPtr & (RTGCPTR)(_4K - 1));
     514        pWalk->GCPhys = (RTGCPHYS)(Desc & fNextTableOrPageMask) | (GCPtr & offPageMask);
    433515        return VINF_SUCCESS;
    434516    }
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