VirtualBox

Changeset 105600 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Aug 6, 2024 9:39:44 AM (7 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164279
Message:

VMM/ARM: Move the VBox ARMv8 platform descriptor from the end of the address space right after the UEFI region, bugref:10746

The original solution was to avoid as many hardcoded addresses as possible by placing the VBox region descriptor right at the end
of the guest physical address space. This turned out to be a bad idea because on M3 the host maximum physical address width and
guest maxmium physical address width differ so mapping the platform descriptor fails. Also saved states would not be portable if
a saved state is mvoed between systems with different physical address widths.
The solution is to move the platform descriptor right after the UEFI region and move the MMIO region, which grew from top to bottom
to start right after the base RAM region and grow upwards.

Location:
trunk/src/VBox/Main/src-client
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/ConsoleImplConfigArmV8.cpp

    r104386 r105600  
    108108#define VRC()       AssertLogRelMsgReturnStmt(RT_SUCCESS(vrc), ("vrc=%Rrc\n", vrc), RTFdtDestroy(hFdt), vrc)
    109109
    110     /** @todo Find a way to figure it out before CPUM is set up, can't use CPUMGetGuestAddrWidths() and on macOS we need
    111      * access to Hypervisor.framework to query the ID registers (Linux can in theory parse /proc/cpuinfo, no idea for Windows). */
    112     RTGCPHYS GCPhysTopOfAddrSpace = RT_BIT_64(36);
    113 
    114110    /*
    115111     * Get necessary objects and frequently used parameters.
     
    187183    BusAssignmentManager *pBusMgr = mBusMgr = BusAssignmentManager::createInstance(pVMM, chipsetType, IommuType_None);
    188184    ResourceAssignmentManager *pResMgr = ResourceAssignmentManager::createInstance(pVMM, chipsetType, IommuType_None,
    189                                                                                    GCPhysTopOfAddrSpace - sizeof(VBOXPLATFORMARMV8),
    190                                                                                    _1G,             /*GCPhysRam*/
    191                                                                                    128 * _1M,       /*GCPhysMmio32Start*/
    192                                                                                    _1G - 128 * _1M, /*cbMmio32*/
    193                                                                                    32               /*cInterrupts*/);
     185                                                                                   RT_MAX(_1G + cbRam, _4G),                  /*GCPhysMmio*/
     186                                                                                   _1G,                                       /*GCPhysRam*/
     187                                                                                   VBOXPLATFORMARMV8_PHYS_ADDR + _1M,         /*GCPhysMmio32Start*/
     188                                                                                   _1G - (VBOXPLATFORMARMV8_PHYS_ADDR + _1M), /*cbMmio32*/
     189                                                                                   32                                         /*cInterrupts*/);
    194190
    195191    /*
     
    332328
    333329        vrc = RTFdtNodeFinalize(hFdt);                                                      VRC();
     330
     331
     332        /*
     333         * CPUM values.
     334         */
     335        PCFGMNODE pCpum;
     336        InsertConfigNode(pRoot, "CPUM", &pCpum);
    334337
    335338
     
    398401        InsertConfigNode(pResources,    "ArmV8Desc",             &pRes);
    399402        InsertConfigInteger(pRes,       "RegisterAsRom",         1);
    400         InsertConfigInteger(pRes,       "GCPhysLoadAddress",     UINT64_MAX); /* End of physical address space. */
     403        InsertConfigInteger(pRes,       "GCPhysLoadAddress",     VBOXPLATFORMARMV8_PHYS_ADDR);
    401404        InsertConfigString(pRes,        "ResourceId",            "VBoxArmV8Desc");
    402405
     
    613616        RTGCPHYS GCPhysPciMmioEcam, GCPhysPciMmio, GCPhysPciMmio32;
    614617        RTGCPHYS cbPciMmioEcam, cbPciMmio, cbPciMmio32;
    615         hrc = pResMgr->assignMmioRegionAligned("pci-pio",    _64K, _64K,         &GCPhysMmioStart,   &cbMmio);         H();
    616         hrc = pResMgr->assignMmioRegion(       "pci-ecam",   16 * _1M,           &GCPhysPciMmioEcam, &cbPciMmioEcam);  H();
    617         hrc = pResMgr->assignMmioRegion(       "pci-mmio",   _2G,                &GCPhysPciMmio,     &cbPciMmio);      H();
    618         hrc = pResMgr->assignMmio32Region(     "pci-mmio32", (1024 - 128) * _1M, &GCPhysPciMmio32,   &cbPciMmio32);    H();
     618        hrc = pResMgr->assignMmioRegionAligned("pci-pio",    _64K, _64K,                              &GCPhysMmioStart,   &cbMmio);         H();
     619        hrc = pResMgr->assignMmioRegion(       "pci-ecam",   16 * _1M,                                &GCPhysPciMmioEcam, &cbPciMmioEcam);  H();
     620        hrc = pResMgr->assignMmioRegion(       "pci-mmio",   _2G,                                     &GCPhysPciMmio,     &cbPciMmio);      H();
     621        hrc = pResMgr->assignMmio32Region(     "pci-mmio32", _1G - VBOXPLATFORMARMV8_PHYS_ADDR - _1M, &GCPhysPciMmio32,   &cbPciMmio32);    H();
    619622
    620623        InsertConfigNode(pDevices, "pci-generic-ecam",  &pDev);
     
    773776    VBOXPLATFORMARMV8 ArmV8Platform; RT_ZERO(ArmV8Platform);
    774777
     778    /* Make room for the descriptor at the beginning. */
     779    vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, sizeof(ArmV8Platform));
     780    AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
     781
    775782    vrc = RTFdtDumpToVfsIoStrm(hFdt, RTFDTTYPE_DTB, 0 /*fFlags*/, hVfsIosDesc, NULL /*pErrInfo*/);
     783    uint64_t cbFdt = 0;
    776784    if (RT_SUCCESS(vrc))
    777         vrc = RTVfsFileQuerySize(hVfsFileDesc, &ArmV8Platform.cbFdt);
     785    {
     786        vrc = RTVfsFileQuerySize(hVfsFileDesc, &cbFdt);
     787        cbFdt -= sizeof(ArmV8Platform);
     788    }
    778789    AssertRCReturnStmt(vrc, RTFdtDestroy(hFdt), vrc);
    779790
    780     vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, (RTFOFF)(RT_ALIGN_64(ArmV8Platform.cbFdt, _64K) - ArmV8Platform.cbFdt));
     791    vrc = RTVfsIoStrmZeroFill(hVfsIosDesc, (RTFOFF)(RT_ALIGN_64(cbFdt, _64K) - cbFdt));
    781792    AssertRCReturn(vrc, vrc);
    782793
     
    797808    ArmV8Platform.u64PhysAddrRamBase  = GCPhysRam;
    798809    ArmV8Platform.cbRamBase           = cbRam;
    799     ArmV8Platform.u64OffBackFdt       = RT_ALIGN_64(ArmV8Platform.cbFdt, _64K);
    800     ArmV8Platform.cbFdt               = RT_ALIGN_64(ArmV8Platform.cbFdt, _64K);
    801     ArmV8Platform.u64OffBackAcpiXsdp  = 0;
     810    ArmV8Platform.i64OffFdt           = sizeof(ArmV8Platform);
     811    ArmV8Platform.cbFdt               = RT_ALIGN_64(cbFdt, _64K);
     812    ArmV8Platform.i64OffAcpiXsdp      = 0;
    802813    ArmV8Platform.cbAcpiXsdp          = 0;
    803     ArmV8Platform.u64OffBackUefiRom   = GCPhysTopOfAddrSpace - sizeof(ArmV8Platform);
    804     ArmV8Platform.cbUefiRom           = _64M; /** @todo Fixed reservation but the ROM region is usually much smaller. */
    805     ArmV8Platform.u64OffBackMmio      = GCPhysTopOfAddrSpace - sizeof(ArmV8Platform) - GCPhysMmioStart;
     814    ArmV8Platform.i64OffUefiRom       = -128 * _1M;
     815    ArmV8Platform.cbUefiRom           = _64M;
     816    ArmV8Platform.i64OffMmio          = GCPhysMmioStart - _128M;
    806817    ArmV8Platform.cbMmio              = cbMmio;
    807     ArmV8Platform.u64OffBackMmio32    = GCPhysTopOfAddrSpace - sizeof(ArmV8Platform) - GCPhysMmio32Start;
     818    ArmV8Platform.i64OffMmio32        = GCPhysMmio32Start - _128M;
    808819    ArmV8Platform.cbMmio32            = cbMmio32;
    809820
    810821    /* Add the VBox platform descriptor to the resource store. */
    811     vrc = RTVfsIoStrmWrite(hVfsIosDesc, &ArmV8Platform, sizeof(ArmV8Platform), true /*fBlocking*/, NULL /*pcbWritten*/);
     822    vrc = RTVfsIoStrmWriteAt(hVfsIosDesc, 0, &ArmV8Platform, sizeof(ArmV8Platform), true /*fBlocking*/, NULL /*pcbWritten*/);
    812823    RTVfsIoStrmRelease(hVfsIosDesc);
    813824    vrc = mptrResourceStore->i_addItem("resources", "VBoxArmV8Desc", hVfsFileDesc);
  • trunk/src/VBox/Main/src-client/ResourceAssignmentManager.cpp

    r104028 r105600  
    113113
    114114HRESULT ResourceAssignmentManager::State::init(PCVMMR3VTABLE pVMM, ChipsetType_T chipsetType, IommuType_T iommuType,
    115                                                RTGCPHYS GCPhysMmioTop, RTGCPHYS GCPhysRamStart,
     115                                               RTGCPHYS GCPhysMmioStart, RTGCPHYS GCPhysRamStart,
    116116                                               RTGCPHYS GCPhysMmio32Start, RTGCPHYS cbMmio32, uint32_t cInterrupts)
    117117{
     
    123123    mChipsetType           = chipsetType;
    124124    mIommuType             = iommuType;
    125     mGCPhysMmioStart       = GCPhysMmioTop;
    126     mGCPhysMmioStartOrig   = GCPhysMmioTop;
     125    mGCPhysMmioStart       = GCPhysMmioStart;
     126    mGCPhysMmioStartOrig   = GCPhysMmioStart;
    127127    mGCPhysRamStart        = GCPhysRamStart;
    128128    mGCPhysMmio32Start     = GCPhysMmio32Start;
     
    171171{
    172172    RTGCPHYS cbRegionAligned = RT_ALIGN_T(cbRegion, _4K, RTGCPHYS);
    173     RTGCPHYS GCPhysMmioStart = pState->mGCPhysMmioStart - cbRegionAligned;
    174 
    175     if (GCPhysMmioStart < pState->mGCPhysRamStart)
    176     {
    177         AssertLogRelMsgFailed(("ResourceAssignmentManager: MMIO range for %s would overlap RAM region\n", pszName));
    178         return E_INVALIDARG;
    179     }
     173    RTGCPHYS GCPhysMmioStart = pState->mGCPhysMmioStart;
    180174
    181175    *pGCPhysStart = GCPhysMmioStart;
    182176    *pcbRegion    = cbRegionAligned;
    183     pState->mGCPhysMmioStart -= cbRegionAligned;
     177    pState->mGCPhysMmioStart += cbRegionAligned;
    184178    pState->addAddrRange(pszName, GCPhysMmioStart, cbRegionAligned);
    185179    return S_OK;
     
    207201{
    208202    RTGCPHYS cbRegionAligned = RT_ALIGN_T(cbRegion, cbAlignment, RTGCPHYS);
    209     RTGCPHYS GCPhysMmioStart = pState->mGCPhysMmioStart - cbRegionAligned;
    210 
    211     GCPhysMmioStart = GCPhysMmioStart & ~(cbAlignment - 1);
    212     if (GCPhysMmioStart < pState->mGCPhysRamStart)
    213     {
    214         AssertLogRelMsgFailed(("ResourceAssignmentManager: MMIO range for %s would overlap RAM region\n", pszName));
    215         return E_INVALIDARG;
    216     }
     203    RTGCPHYS GCPhysMmioStart = pState->mGCPhysMmioStart;
     204
     205    GCPhysMmioStart = RT_ALIGN_T(GCPhysMmioStart, cbAlignment, RTGCPHYS);
    217206
    218207    *pGCPhysStart = GCPhysMmioStart;
    219208    *pcbRegion    = cbRegionAligned;
    220     pState->mGCPhysMmioStart = GCPhysMmioStart;
     209    pState->mGCPhysMmioStart = GCPhysMmioStart + cbRegionAligned;
    221210    pState->addAddrRange(pszName, GCPhysMmioStart, cbRegionAligned);
    222211    return S_OK;
     
    232221HRESULT ResourceAssignmentManager::assignRamRegion(const char *pszName, RTGCPHYS cbRam, PRTGCPHYS pGCPhysStart)
    233222{
    234     if (pState->mGCPhysRamStart + cbRam > pState->mGCPhysMmioStart)
    235     {
    236         AssertLogRelMsgFailed(("ResourceAssignmentManager: RAM range for %s would overlap MMIO range\n", pszName));
    237         return E_INVALIDARG;
    238     }
    239 
    240223    *pGCPhysStart = pState->mGCPhysRamStart;
    241224    pState->mGCPhysRamStart += cbRam;
     
    264247HRESULT ResourceAssignmentManager::queryMmioRegion(PRTGCPHYS pGCPhysMmioStart, PRTGCPHYS pcbMmio)
    265248{
    266     *pGCPhysMmioStart = pState->mGCPhysMmioStart;
    267     *pcbMmio          = pState->mGCPhysMmioStartOrig - pState->mGCPhysMmioStart;
     249    *pGCPhysMmioStart = pState->mGCPhysMmioStartOrig;
     250    *pcbMmio          = pState->mGCPhysMmioStart - pState->mGCPhysMmioStartOrig;
    268251    return S_OK;
    269252}
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