VirtualBox

Changeset 45024 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 13, 2013 3:58:02 PM (12 years ago)
Author:
vboxsync
Message:

PDM,PGM,DevEFI,DevACPI,DevPcBios: Added memory setup phase after construction and reset to solve PGM/PDM reset order issue (PDM first, then PGM, only that wasn't possible previously since PDM reset would plant stuff in guest RAM).

Location:
trunk/src/VBox
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/DevEFI.cpp

    r44820 r45024  
    13831383}
    13841384
    1385 /**
    1386  * Reset notification.
    1387  *
    1388  * @returns VBox status.
    1389  * @param   pDevIns     The device instance data.
     1385
     1386/**
     1387 * @interface_method_impl{PDMDEVREG,pfnMemSetup}
     1388 */
     1389static DECLCALLBACK(void) efiMemSetup(PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx)
     1390{
     1391    PDEVEFI pThis = PDMINS_2_DATA(pDevIns, PDEVEFI);
     1392
     1393    /*
     1394     * Plan some structures in RAM.
     1395     */
     1396    FwCommonPlantSmbiosAndDmiHdrs(pDevIns, pThis->cbDmiTables, pThis->cNumDmiTables);
     1397    if (pThis->u8IOAPIC)
     1398        FwCommonPlantMpsFloatPtr(pDevIns);
     1399
     1400    /*
     1401     * Re-shadow the Firmware Volume and make it RAM/RAM.
     1402     */
     1403    uint32_t    cPages = RT_ALIGN_64(pThis->cbEfiRom, PAGE_SIZE) >> PAGE_SHIFT;
     1404    RTGCPHYS    GCPhys = pThis->GCLoadAddress;
     1405    while (cPages > 0)
     1406    {
     1407        uint8_t abPage[PAGE_SIZE];
     1408
     1409        /* Read the (original) ROM page and write it back to the RAM page. */
     1410        int rc = PDMDevHlpROMProtectShadow(pDevIns, GCPhys, PAGE_SIZE, PGMROMPROT_READ_ROM_WRITE_RAM);
     1411        AssertLogRelRC(rc);
     1412
     1413        rc = PDMDevHlpPhysRead(pDevIns, GCPhys, abPage, PAGE_SIZE);
     1414        AssertLogRelRC(rc);
     1415        if (RT_FAILURE(rc))
     1416            memset(abPage, 0xcc, sizeof(abPage));
     1417
     1418        rc = PDMDevHlpPhysWrite(pDevIns, GCPhys, abPage, PAGE_SIZE);
     1419        AssertLogRelRC(rc);
     1420
     1421        /* Switch to the RAM/RAM mode. */
     1422        rc = PDMDevHlpROMProtectShadow(pDevIns, GCPhys, PAGE_SIZE, PGMROMPROT_READ_RAM_WRITE_RAM);
     1423        AssertLogRelRC(rc);
     1424
     1425        /* Advance */
     1426        GCPhys += PAGE_SIZE;
     1427        cPages--;
     1428    }
     1429}
     1430
     1431
     1432/**
     1433 * @interface_method_impl{PDMDEVREG,pfnReset}
    13901434 */
    13911435static DECLCALLBACK(void) efiReset(PPDMDEVINS pDevIns)
    13921436{
    13931437    PDEVEFI  pThis = PDMINS_2_DATA(pDevIns, PDEVEFI);
    1394     int rc;
    13951438
    13961439    LogFlow(("efiReset\n"));
     
    14031446    pThis->iPanicMsg = 0;
    14041447    pThis->szPanicMsg[0] = '\0';
    1405 
    1406     /*
    1407      * Plan some structures in RAM.
    1408      */
    1409     FwCommonPlantSmbiosAndDmiHdrs(pDevIns, pThis->cbDmiTables, pThis->cNumDmiTables);
    1410     if (pThis->u8IOAPIC)
    1411         FwCommonPlantMpsFloatPtr(pDevIns);
    1412 
    1413     /*
    1414      * Re-shadow the Firmware Volume and make it RAM/RAM.
    1415      */
    1416     uint32_t    cPages = RT_ALIGN_64(pThis->cbEfiRom, PAGE_SIZE) >> PAGE_SHIFT;
    1417     RTGCPHYS    GCPhys = pThis->GCLoadAddress;
    1418     while (cPages > 0)
    1419     {
    1420         uint8_t abPage[PAGE_SIZE];
    1421 
    1422         /* Read the (original) ROM page and write it back to the RAM page. */
    1423         rc = PDMDevHlpROMProtectShadow(pDevIns, GCPhys, PAGE_SIZE, PGMROMPROT_READ_ROM_WRITE_RAM);
    1424         AssertLogRelRC(rc);
    1425 
    1426         rc = PDMDevHlpPhysRead(pDevIns, GCPhys, abPage, PAGE_SIZE);
    1427         AssertLogRelRC(rc);
    1428         if (RT_FAILURE(rc))
    1429             memset(abPage, 0xcc, sizeof(abPage));
    1430 
    1431         rc = PDMDevHlpPhysWrite(pDevIns, GCPhys, abPage, PAGE_SIZE);
    1432         AssertLogRelRC(rc);
    1433 
    1434         /* Switch to the RAM/RAM mode. */
    1435         rc = PDMDevHlpROMProtectShadow(pDevIns, GCPhys, PAGE_SIZE, PGMROMPROT_READ_RAM_WRITE_RAM);
    1436         AssertLogRelRC(rc);
    1437 
    1438         /* Advance */
    1439         GCPhys += PAGE_SIZE;
    1440         cPages--;
    1441     }
    1442 }
     1448}
     1449
    14431450
    14441451/**
     
    16871694    return rc;
    16881695}
     1696
    16891697
    16901698/**
     
    19821990    /* pfnRelocate */
    19831991    NULL,
    1984     /* pfnIOCtl */
    1985     NULL,
     1992    /* pfnMemSetup */
     1993    efiMemSetup,
    19861994    /* pfnPowerOn */
    19871995    NULL,
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r44626 r45024  
    28052805
    28062806/**
     2807 * @interface_method_impl{PDMDEVREG,pfnMemSetup}
     2808 */
     2809static DECLCALLBACK(void) acpiR3MemSetup(PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx)
     2810{
     2811    ACPIState *pThis = PDMINS_2_DATA(pDevIns, ACPIState *);
     2812    acpiR3PlantTables(pThis);
     2813}
     2814
     2815/**
    28072816 * @interface_method_impl{PDMDEVREG,pfnReset}
    28082817 */
     
    28262835    /** @todo Should we really reset PM base? */
    28272836    acpiR3UpdatePmHandlers(pThis, PM_PORT_BASE);
    2828 
    2829     acpiR3PlantTables(pThis);
    28302837}
    28312838
     
    32173224     * Plant ACPI tables.
    32183225     */
     3226    /** @todo Part of this is redone by acpiR3MemSetup, we only need to init the
     3227     *        au8RSDPPage here. However, there should be no harm in doing it
     3228     *        twice, so the lazy bird is taking the quick way out for now. */
    32193229    RTGCPHYS32 GCPhysRsdp = apicR3FindRsdpSpace();
    32203230    if (!GCPhysRsdp)
     
    33723382    /* pfnRelocate */
    33733383    acpiR3Relocate,
    3374     /* pfnIOCtl */
    3375     NULL,
     3384    /* pfnMemSetup */
     3385    acpiR3MemSetup,
    33763386    /* pfnPowerOn */
    33773387    NULL,
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r44821 r45024  
    765765
    766766/**
    767  * @interface_method_impl{PDMDEVREG,pfnReset}
    768  */
    769 static DECLCALLBACK(void) pcbiosReset(PPDMDEVINS pDevIns)
     767 * @interface_method_impl{PDMDEVREG,pfnMemSetup}
     768 */
     769static DECLCALLBACK(void) pcbiosMemSetup(PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx)
    770770{
    771771    PDEVPCBIOS  pThis = PDMINS_2_DATA(pDevIns, PDEVPCBIOS);
    772     LogFlow(("pcbiosReset:\n"));
     772    LogFlow(("pcbiosMemSetup:\n"));
    773773
    774774    if (pThis->u8IOAPIC)
     
    14231423        pThis->uBootDelay = 15;
    14241424
    1425     /*
    1426      * Call reset plant tables and shadow the PXE ROM.
    1427      */
    1428     pcbiosReset(pDevIns);
    1429 
    14301425    return VINF_SUCCESS;
    14311426}
     
    14621457    NULL,
    14631458    /* pfnIOCtl */
    1464     NULL,
     1459    pcbiosMemSetup,
    14651460    /* pfnPowerOn */
    14661461    NULL,
    14671462    /* pfnReset */
    1468     pcbiosReset,
     1463    NULL,
    14691464    /* pfnSuspend */
    14701465    NULL,
  • trunk/src/VBox/VMM/VMMR3/PDM.cpp

    r44399 r45024  
    15071507
    15081508    LogFlow(("PDMR3Reset: returns void\n"));
     1509}
     1510
     1511
     1512/**
     1513 * This function will tell all the devices to setup up their memory structures
     1514 * after VM construction and after VM reset.
     1515 *
     1516 * @param   pVM         Pointer to the VM.
     1517 * @param   fAtReset    Indicates the context, after reset if @c true or after
     1518 *                      construction if @c false.
     1519 */
     1520VMMR3_INT_DECL(void) PDMR3MemSetup(PVM pVM, bool fAtReset)
     1521{
     1522    LogFlow(("PDMR3MemSetup: fAtReset=%RTbool\n", fAtReset));
     1523    PDMDEVMEMSETUPCTX const enmCtx = fAtReset ? PDMDEVMEMSETUPCTX_AFTER_RESET : PDMDEVMEMSETUPCTX_AFTER_CONSTRUCTION;
     1524
     1525    /*
     1526     * Iterate thru the device instances and work the callback.
     1527     */
     1528    for (PPDMDEVINS pDevIns = pVM->pdm.s.pDevInstances; pDevIns; pDevIns = pDevIns->Internal.s.pNextR3)
     1529        if (pDevIns->pReg->pfnMemSetup)
     1530        {
     1531            PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
     1532            pDevIns->pReg->pfnMemSetup(pDevIns, enmCtx);
     1533            PDMCritSectLeave(pDevIns->pCritSectRoR3);
     1534        }
     1535
     1536    LogFlow(("PDMR3MemSetup: returns void\n"));
    15091537}
    15101538
  • trunk/src/VBox/VMM/VMMR3/PGM.cpp

    r44730 r45024  
    25032503 * @param   pVM     Pointer to the VM.
    25042504 */
    2505 VMMR3DECL(void) PGMR3Reset(PVM pVM)
     2505VMMR3_INT_DECL(void) PGMR3Reset(PVM pVM)
    25062506{
    25072507    int rc;
     
    25812581    }
    25822582
    2583     /*
    2584      * Reset (zero) RAM and shadow ROM pages.
    2585      */
    2586     rc = pgmR3PhysRamReset(pVM);
    2587     if (RT_SUCCESS(rc))
    2588         rc = pgmR3PhysRomReset(pVM);
    2589 
    2590 
    25912583    pgmUnlock(pVM);
    25922584    AssertReleaseRC(rc);
     2585}
     2586
     2587
     2588/**
     2589 * Memory setup after VM construction or reset.
     2590 *
     2591 * @param   pVM         Pointer to the VM.
     2592 * @param   fAtReset    Indicates the context, after reset if @c true or after
     2593 *                      construction if @c false.
     2594 */
     2595VMMR3_INT_DECL(void) PGMR3MemSetup(PVM pVM, bool fAtReset)
     2596{
     2597    if (fAtReset)
     2598    {
     2599        pgmLock(pVM);
     2600
     2601        int rc = pgmR3PhysRamZeroAll(pVM); AssertLogRelRC(rc);
     2602        rc = pgmR3PhysRomReset(pVM); AssertLogRelRC(rc);
     2603
     2604        pgmUnlock(pVM);
     2605    }
    25932606}
    25942607
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r44528 r45024  
    18851885
    18861886/**
    1887  * Resets (zeros) the RAM.
     1887 * Resets the physical memory state.
    18881888 *
    18891889 * ASSUMES that the caller owns the PGM lock.
     
    19101910    pVM->pgm.s.cBalloonedPages    = 0;
    19111911
     1912    return VINF_SUCCESS;
     1913}
     1914
     1915
     1916/**
     1917 * Resets (zeros) the RAM after all devices and components have been reset.
     1918 *
     1919 * ASSUMES that the caller owns the PGM lock.
     1920 *
     1921 * @returns VBox status code.
     1922 * @param   pVM     Pointer to the VM.
     1923 */
     1924int pgmR3PhysRamZeroAll(PVM pVM)
     1925{
     1926    PGM_LOCK_ASSERT_OWNER(pVM);
     1927
    19121928    /*
    19131929     * We batch up pages that should be freed instead of calling GMM for
     
    19161932    uint32_t            cPendingPages = 0;
    19171933    PGMMFREEPAGESREQ    pReq;
    1918     rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE);
     1934    int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE);
    19191935    AssertLogRelRCReturn(rc, rc);
    19201936
     
    20432059    }
    20442060    GMMR3FreePagesCleanup(pReq);
    2045 
    20462061    return VINF_SUCCESS;
    20472062}
     
    35523567
    35533568/**
    3554  * Called by PGMR3Reset to reset the shadow, switch to the virgin,
    3555  * and verify that the virgin part is untouched.
     3569 * Called by PGMR3MemSetup to reset the shadow, switch to the virgin, and verify
     3570 * that the virgin part is untouched.
    35563571 *
    35573572 * This is done after the normal memory has been cleared.
  • trunk/src/VBox/VMM/VMMR3/VM.cpp

    r45006 r45024  
    964964#endif
    965965                                                                        if (RT_SUCCESS(rc))
     966                                                                        {
     967                                                                            PGMR3MemSetup(pVM, false /*fAtReset*/);
     968                                                                            PDMR3MemSetup(pVM, false /*fAtReset*/);
     969                                                                        }
     970                                                                        if (RT_SUCCESS(rc))
    966971                                                                            rc = vmR3InitDoCompleted(pVM, VMINITCOMPLETED_RING3);
    967972                                                                        if (RT_SUCCESS(rc))
     
    26872692        PATMR3Reset(pVM);
    26882693        CSAMR3Reset(pVM);
    2689         PGMR3Reset(pVM);                    /* We clear VM RAM in PGMR3Reset. It's vital PDMR3Reset is executed
    2690                                              * _afterwards_. E.g. ACPI sets up RAM tables during init/reset. */
    2691 /** @todo PGMR3Reset should be called after PDMR3Reset really, because we'll trash OS <-> hardware
    2692  * communication structures residing in RAM when done in the other order.  I.e. the device must be
    2693  * quiesced first, then we clear the memory and plan tables. Probably have to make these things
    2694  * explicit in some way, some memory setup pass or something.
    2695  * (Example: DevAHCI may assert if memory is zeroed before it has read the FIS.)
    2696  *
    2697  * @bugref{4467}
    2698  */
    26992694        PDMR3Reset(pVM);
     2695        PGMR3Reset(pVM);
    27002696        SELMR3Reset(pVM);
    27012697        TRPMR3Reset(pVM);
     
    27052701        IOMR3Reset(pVM);
    27062702        CPUMR3Reset(pVM);
    2707     }
    2708     if (pVCpu->idCpu == 0)
    2709     {
    27102703        TMR3Reset(pVM);
    27112704        EMR3Reset(pVM);
     
    27192712        DBGFR3Info(pVM->pUVM, "cpum", "verbose", NULL);
    27202713#endif
     2714
     2715        /*
     2716         * Do memory setup.
     2717         */
     2718        PGMR3MemSetup(pVM, true /*fAtReset*/);
     2719        PDMR3MemSetup(pVM, true /*fAtReset*/);
    27212720
    27222721        /*
  • trunk/src/VBox/VMM/include/PGMInternal.h

    r44528 r45024  
    39613961int             pgmR3PhysRamReset(PVM pVM);
    39623962int             pgmR3PhysRomReset(PVM pVM);
     3963int             pgmR3PhysRamZeroAll(PVM pVM);
    39633964int             pgmR3PhysChunkMap(PVM pVM, uint32_t idChunk, PPPGMCHUNKR3MAP ppChunk);
    39643965int             pgmR3PhysRamTerm(PVM pVM);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette