VirtualBox

Changeset 77299 in vbox


Ignore:
Timestamp:
Feb 13, 2019 1:57:14 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
128819
Message:

DevVGA,PCI,PGM: Hacks for making it possible to load saved states of the VBoxSVGA device with the 'wrong' BAR layout. bugref:9359

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmdev.h

    r77253 r77299  
    18901890
    18911891/** Current PDMDEVHLPR3 version number. */
    1892 #define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 22, 1)
     1892#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 22, 2)
    18931893
    18941894/**
     
    33803380    DECLR3CALLBACKMEMBER(void, pfnPhysBulkReleasePageMappingLocks,(PPDMDEVINS pDevIns, uint32_t cPages, PPGMPAGEMAPLOCK paLocks));
    33813381
     3382    /**
     3383     * Changes the number of an MMIO2 or pre-registered MMIO region.
     3384     *
     3385     * This should only be used to deal with saved state problems, so there is no
     3386     * convenience inline wrapper for this method.
     3387     *
     3388     * @returns VBox status code.
     3389     * @param   pDevIns             The device instance.
     3390     * @param   pPciDev             The PCI device the region is associated with, or
     3391     *                              NULL if not associated with any.
     3392     * @param   iRegion             The region.
     3393     * @param   iNewRegion          The new region index.
     3394     *
     3395     * @sa      @bugref{9359}
     3396     */
     3397    DECLR3CALLBACKMEMBER(int, pfnMMIOExChangeRegionNo,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
     3398                                                       uint32_t iNewRegion));
     3399
    33823400    /** Space reserved for future members.
    33833401     * @{ */
     
    33883406    DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
    33893407    DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
    3390     DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
     3408    /*DECLR3CALLBACKMEMBER(void, pfnReserved7,(void)); */
    33913409    /*DECLR3CALLBACKMEMBER(void, pfnReserved8,(void)); */
    33923410    /*DECLR3CALLBACKMEMBER(void, pfnReserved9,(void)); */
  • trunk/include/VBox/vmm/pdmpcidev.h

    r76585 r77299  
    122122typedef FNPCIIOREGIONOLDSETTER *PFNPCIIOREGIONOLDSETTER;
    123123
     124/**
     125 * Swaps two PCI I/O regions from within a PDMPCIDEV::pfnRegionLoadChangeHookR3
     126 * callback.
     127 *
     128 * @returns VBox status code.
     129 * @param   pPciDev         Pointer to the PCI device.
     130 * @param   iRegion         The region number.
     131 * @param   iOtherRegion    The number of the region swap with.
     132 * @sa      @bugref{9359}
     133 */
     134typedef DECLCALLBACK(int) FNPCIIOREGIONSWAP(PPDMPCIDEV pPciDev, uint32_t iRegion, uint32_t iOtherRegion);
     135/** Pointer to a FNPCIIOREGIONSWAP() function. */
     136typedef FNPCIIOREGIONSWAP *PFNPCIIOREGIONSWAP;
    124137
    125138
     
    188201     * @param   pfnOldSetter    Callback for setting size and type for call
    189202     *                          regarding old saved states.  NULL otherwise.
     203     * @param   pfnSwapRegions  Used to swaps two regions. The second one must be a
     204     *                          higher number than @a iRegion.  NULL if old saved
     205     *                          state.
    190206     */
    191207    DECLR3CALLBACKMEMBER(int, pfnRegionLoadChangeHookR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
    192208                                                         uint64_t cbRegion, PCIADDRESSSPACE enmType,
    193                                                          PFNPCIIOREGIONOLDSETTER pfnOldSetter));
     209                                                         PFNPCIIOREGIONOLDSETTER pfnOldSetter,
     210                                                         PFNPCIIOREGIONSWAP pfnSwapRegion));
    194211} PDMPCIDEV;
    195212#ifdef PDMPCIDEVINT_DECLARED
  • trunk/include/VBox/vmm/pgm.h

    r77241 r77299  
    842842VMMR3_INT_DECL(int) PGMR3PhysMMIO2GetHCPhys(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, PRTHCPHYS pHCPhys);
    843843VMMR3_INT_DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr);
     844VMMR3_INT_DECL(int) PGMR3PhysMMIOExChangeRegionNo(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion, uint32_t iNewRegion);
     845
    844846
    845847/** @name PGMR3PhysRegisterRom flags.
  • trunk/src/VBox/Devices/Graphics/DevVGA.cpp

    r77289 r77299  
    55555555static DECLCALLBACK(int) vgaR3PciRegionLoadChangeHook(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
    55565556                                                      uint64_t cbRegion, PCIADDRESSSPACE enmType,
    5557                                                       PFNPCIIOREGIONOLDSETTER pfnOldSetter)
     5557                                                      PFNPCIIOREGIONOLDSETTER pfnOldSetter, PFNPCIIOREGIONSWAP pfnSwapRegions)
    55585558{
    55595559    PVGASTATE pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
    55605560
    55615561# ifdef VBOX_WITH_VMSVGA
    5562     /*
    5563      * The VMSVGA changed the default FIFO size from 128KB to 2MB after 5.1.
    5564      */
    55655562    if (pThis->fVMSVGAEnabled)
    55665563    {
     5564        /*
     5565         * We messed up BAR order for the hybrid devices in 6.0 (see #9359).
     5566         * It should have been compatible with the VBox VGA device and had the
     5567         * VRAM region first and I/O second, but instead the I/O region ended
     5568         * up first and VRAM second like the VMSVGA device.
     5569         *
     5570         * So, we have to detect that here and reconfigure the memory regions.
     5571         * Region numbers are used in our (and the PCI bus') interfaction with
     5572         * PGM, so PGM needs to be informed too.
     5573         */
     5574        if (   iRegion == 0
     5575            && iRegion == pThis->pciRegions.iVRAM
     5576            && (enmType & PCI_ADDRESS_SPACE_IO))
     5577        {
     5578            LogRel(("VGA: Detected old BAR config, making adjustments.\n"));
     5579
     5580            /* Update the entries. */
     5581            pThis->pciRegions.iIO   = 0;
     5582            pThis->pciRegions.iVRAM = 1;
     5583
     5584            /* Update PGM on the region number change so it won't barf when restoring state. */
     5585            AssertLogRelReturn(pDevIns->CTX_SUFF(pHlp)->pfnMMIOExChangeRegionNo, VERR_VERSION_MISMATCH);
     5586            int rc = pDevIns->CTX_SUFF(pHlp)->pfnMMIOExChangeRegionNo(pDevIns, pPciDev, 0, 1);
     5587            AssertLogRelRCReturn(rc, rc);
     5588
     5589            /* Update the calling PCI device. */
     5590            AssertLogRelReturn(pfnSwapRegions, VERR_INTERNAL_ERROR_2);
     5591            rc = pfnSwapRegions(pPciDev, 0, 1);
     5592            AssertLogRelRCReturn(rc, rc);
     5593
     5594            return rc;
     5595        }
     5596
     5597        /*
     5598         * The VMSVGA changed the default FIFO size from 128KB to 2MB after 5.1.
     5599         */
    55675600        if (iRegion == pThis->pciRegions.iFIFO)
    55685601        {
     
    55915624
    55925625        }
     5626
    55935627        /* Emulate callbacks for 5.1 and older saved states by recursion. */
    5594         else if (iRegion == UINT32_MAX)
     5628        if (iRegion == UINT32_MAX)
    55955629        {
    5596             int rc = vgaR3PciRegionLoadChangeHook(pDevIns, pPciDev, pThis->pciRegions.iFIFO, VMSVGA_FIFO_SIZE_OLD, PCI_ADDRESS_SPACE_MEM, NULL);
     5630            int rc = vgaR3PciRegionLoadChangeHook(pDevIns, pPciDev, pThis->pciRegions.iFIFO, VMSVGA_FIFO_SIZE_OLD,
     5631                                                  PCI_ADDRESS_SPACE_MEM, NULL, NULL);
    55975632            if (RT_SUCCESS(rc))
    55985633                rc = pfnOldSetter(pPciDev, pThis->pciRegions.iFIFO, VMSVGA_FIFO_SIZE_OLD, PCI_ADDRESS_SPACE_MEM);
     
    62596294    Log(("VMSVGA: VMSVGAPciId   = %d\n", pThis->fVMSVGAPciId));
    62606295
    6261     rc = CFGMR3QueryBoolDef(pCfg, "VMSVGAPciBarLayout", &pThis->fVMSVGAPciBarLayout, false);
     6296    rc = CFGMR3QueryBoolDef(pCfg, "VMSVGAPciBarLayout", &pThis->fVMSVGAPciBarLayout, pThis->fVMSVGAPciId);
    62626297    AssertLogRelRCReturn(rc, rc);
    62636298    Log(("VMSVGA: VMSVGAPciBarLayout = %d\n", pThis->fVMSVGAPciBarLayout));
     
    62826317        pThis->pciRegions.iIO   = 0;
    62836318        pThis->pciRegions.iVRAM = 1;
    6284         pThis->pciRegions.iFIFO = 2;
    62856319    }
    62866320    else
     
    62886322        pThis->pciRegions.iVRAM = 0;
    62896323        pThis->pciRegions.iIO   = 1;
    6290         pThis->pciRegions.iFIFO = 2;
    6291     }
     6324    }
     6325    pThis->pciRegions.iFIFO = 2;
    62926326#else
    62936327    pThis->pciRegions.iVRAM = 0;
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r77249 r77299  
    663663
    664664    LogFlow(("pdmR3DevHlp_MMIO2MapKernel: caller='%s'/%d: returns %Rrc *pR0Ptr=%RHv\n", pDevIns->pReg->szName, pDevIns->iInstance, rc, *pR0Ptr));
     665    return rc;
     666}
     667
     668
     669/**
     670 * @copydoc PDMDEVHLPR3::pfnMMIOExChangeRegionNo
     671 */
     672static DECLCALLBACK(int) pdmR3DevHlp_MMIOExChangeRegionNo(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
     673                                                          uint32_t iNewRegion)
     674{
     675    PDMDEV_ASSERT_DEVINS(pDevIns);
     676    PVM pVM = pDevIns->Internal.s.pVMR3;
     677    VM_ASSERT_EMT(pVM);
     678    LogFlow(("pdmR3DevHlp_MMIOExChangeRegionNo: caller='%s'/%d: pPciDev=%p:{%#x} iRegion=%#x iNewRegion=%#x\n",
     679             pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev ? pPciDev->uDevFn : UINT32_MAX, iRegion, iNewRegion));
     680    AssertReturn(!pPciDev || pPciDev->Int.s.pDevInsR3 == pDevIns, VERR_INVALID_PARAMETER);
     681
     682    int rc = PGMR3PhysMMIOExChangeRegionNo(pVM, pDevIns, pPciDev ? pPciDev->Int.s.idxDevCfg : 254, iRegion, iNewRegion);
     683
     684    LogFlow(("pdmR3DevHlp_MMIOExChangeRegionNo: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
    665685    return rc;
    666686}
     
    37983818    pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
    37993819    pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
    3800     0,
     3820    pdmR3DevHlp_MMIOExChangeRegionNo,
    38013821    0,
    38023822    0,
     
    40684088    pdmR3DevHlp_PhysBulkGCPhys2CCPtrReadOnly,
    40694089    pdmR3DevHlp_PhysBulkReleasePageMappingLocks,
    4070     0,
     4090    pdmR3DevHlp_MMIOExChangeRegionNo,
    40714091    0,
    40724092    0,
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r77249 r77299  
    41694169
    41704170    return rc;
     4171}
     4172
     4173
     4174/**
     4175 * Changes the region number of an MMIO2 or pre-registered MMIO region.
     4176 *
     4177 * This is only for dealing with save state issues, nothing else.
     4178 *
     4179 * @return VBox status code.
     4180 *
     4181 * @param   pVM         The cross context VM structure.
     4182 * @param   pDevIns     The device owning the MMIO2 memory.
     4183 * @param   iSubDev     The sub-device number.
     4184 * @param   iRegion     The region.
     4185 * @param   iNewRegion  The new region index.
     4186 *
     4187 * @sa      @bugref{9359}
     4188 */
     4189VMMR3_INT_DECL(int) PGMR3PhysMMIOExChangeRegionNo(PVM pVM, PPDMDEVINS pDevIns, uint32_t iSubDev, uint32_t iRegion,
     4190                                                  uint32_t iNewRegion)
     4191{
     4192    /*
     4193     * Validate input.
     4194     */
     4195    VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
     4196    AssertPtrReturn(pDevIns, VERR_INVALID_PARAMETER);
     4197    AssertReturn(iSubDev <= UINT8_MAX, VERR_INVALID_PARAMETER);
     4198    AssertReturn(iRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
     4199    AssertReturn(iNewRegion <= UINT8_MAX, VERR_INVALID_PARAMETER);
     4200
     4201    AssertReturn(pVM->enmVMState == VMSTATE_LOADING, VERR_INVALID_STATE);
     4202
     4203    PPGMREGMMIORANGE pFirstRegMmio = pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iRegion);
     4204    AssertReturn(pFirstRegMmio, VERR_NOT_FOUND);
     4205    AssertReturn(pgmR3PhysMMIOExFind(pVM, pDevIns, iSubDev, iNewRegion) == NULL, VERR_RESOURCE_IN_USE);
     4206
     4207    /*
     4208     * Make the change.
     4209     */
     4210    pFirstRegMmio->iRegion = (uint8_t)iNewRegion;
     4211
     4212    return VINF_SUCCESS;
    41714213}
    41724214
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