VirtualBox

Changeset 24582 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Nov 11, 2009 2:38:34 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
54717
Message:

VMM.cpp: Fix cleanup of the stack's guard pages so that we don't assert in PGM if VM creation fails before VMMR3InitFinalize.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

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

    r23801 r24582  
    448448VMMR3DECL(int) VMMR3InitFinalize(PVM pVM)
    449449{
    450     int rc = VINF_SUCCESS;
    451 
     450    int rc;
     451
     452    /*
     453     * Set page attributes to r/w for stack pages.
     454     */
    452455    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    453456    {
    454         PVMCPU pVCpu = &pVM->aCpus[idCpu];
     457        rc = PGMMapSetPage(pVM, pVM->aCpus[idCpu].vmm.s.pbEMTStackRC, VMM_STACK_SIZE,
     458                           X86_PTE_P | X86_PTE_A | X86_PTE_D | X86_PTE_RW);
     459        AssertRCReturn(rc, rc);
     460    }
     461
     462    /*
     463     * Create the EMT yield timer.
     464     */
     465    rc = TMR3TimerCreateInternal(pVM, TMCLOCK_REAL, vmmR3YieldEMT, NULL, "EMT Yielder", &pVM->vmm.s.pYieldTimer);
     466    AssertRCReturn(rc, rc);
     467
     468    rc = TMTimerSetMillies(pVM->vmm.s.pYieldTimer, pVM->vmm.s.cYieldEveryMillies);
     469    AssertRCReturn(rc, rc);
     470
     471#ifdef VBOX_WITH_NMI
     472    /*
     473     * Map the host APIC into GC - This is AMD/Intel + Host OS specific!
     474     */
     475    rc = PGMMap(pVM, pVM->vmm.s.GCPtrApicBase, 0xfee00000, PAGE_SIZE,
     476                X86_PTE_P | X86_PTE_RW | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A | X86_PTE_D);
     477    AssertRCReturn(rc, rc);
     478#endif
    455479
    456480#ifdef VBOX_STRICT_VMM_STACK
    457         /*
    458          * Two inaccessible pages at each sides of the stack to catch over/under-flows.
    459          */
    460         memset(pVCpu->vmm.s.pbEMTStackR3 - PAGE_SIZE, 0xcc, PAGE_SIZE);
    461         MMR3HyperSetGuard(pVM, pVCpu->vmm.s.pbEMTStackR3 - PAGE_SIZE, PAGE_SIZE, true /*fSet*/);
    462 
    463         memset(pVCpu->vmm.s.pbEMTStackR3 + VMM_STACK_SIZE, 0xcc, PAGE_SIZE);
    464         MMR3HyperSetGuard(pVM, pVCpu->vmm.s.pbEMTStackR3 + VMM_STACK_SIZE, PAGE_SIZE, true /*fSet*/);
    465 #endif
    466 
    467         /*
    468          * Set page attributes to r/w for stack pages.
    469          */
    470         rc = PGMMapSetPage(pVM, pVCpu->vmm.s.pbEMTStackRC, VMM_STACK_SIZE, X86_PTE_P | X86_PTE_A | X86_PTE_D | X86_PTE_RW);
    471         AssertRC(rc);
    472         if (RT_FAILURE(rc))
    473             break;
    474     }
    475     if (RT_SUCCESS(rc))
    476     {
    477         /*
    478          * Create the EMT yield timer.
    479          */
    480         rc = TMR3TimerCreateInternal(pVM, TMCLOCK_REAL, vmmR3YieldEMT, NULL, "EMT Yielder", &pVM->vmm.s.pYieldTimer);
    481         if (RT_SUCCESS(rc))
    482            rc = TMTimerSetMillies(pVM->vmm.s.pYieldTimer, pVM->vmm.s.cYieldEveryMillies);
    483     }
    484 
    485 #ifdef VBOX_WITH_NMI
    486     /*
    487      * Map the host APIC into GC - This is AMD/Intel + Host OS specific!
    488      */
    489     if (RT_SUCCESS(rc))
    490         rc = PGMMap(pVM, pVM->vmm.s.GCPtrApicBase, 0xfee00000, PAGE_SIZE,
    491                     X86_PTE_P | X86_PTE_RW | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A | X86_PTE_D);
    492 #endif
    493     return rc;
     481    /*
     482     * Setup the stack guard pages: Two inaccessible pages at each sides of the
     483     * stack to catch over/under-flows.
     484     */
     485    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     486    {
     487        uint8_t *pbEMTStackR3 = pVM->aCpus[idCpu].vmm.s.pbEMTStackR3;
     488
     489        memset(pbEMTStackR3 - PAGE_SIZE, 0xcc, PAGE_SIZE);
     490        MMR3HyperSetGuard(pVM, pbEMTStackR3 - PAGE_SIZE, PAGE_SIZE, true /*fSet*/);
     491
     492        memset(pbEMTStackR3 + VMM_STACK_SIZE, 0xcc, PAGE_SIZE);
     493        MMR3HyperSetGuard(pVM, pbEMTStackR3 + VMM_STACK_SIZE, PAGE_SIZE, true /*fSet*/);
     494    }
     495    pVM->vmm.s.fStackGuardsStationed = true;
     496#endif
     497
     498    return VINF_SUCCESS;
    494499}
    495500
     
    699704     * Make the two stack guard pages present again.
    700705     */
    701     for (VMCPUID i = 0; i < pVM->cCpus; i++)
    702     {
    703         MMR3HyperSetGuard(pVM, pVM->aCpus[i].vmm.s.pbEMTStackR3 - PAGE_SIZE,      PAGE_SIZE, false /*fSet*/);
    704         MMR3HyperSetGuard(pVM, pVM->aCpus[i].vmm.s.pbEMTStackR3 + VMM_STACK_SIZE, PAGE_SIZE, false /*fSet*/);
     706    if (pVM->vmm.s.fStackGuardsStationed)
     707    {
     708        for (VMCPUID i = 0; i < pVM->cCpus; i++)
     709        {
     710            uint8_t *pbEMTStackR3 = pVM->aCpus[i].vmm.s.pbEMTStackR3;
     711            MMR3HyperSetGuard(pVM, pbEMTStackR3 - PAGE_SIZE,      PAGE_SIZE, false /*fSet*/);
     712            MMR3HyperSetGuard(pVM, pbEMTStackR3 + VMM_STACK_SIZE, PAGE_SIZE, false /*fSet*/);
     713        }
     714        pVM->vmm.s.fStackGuardsStationed = false;
    705715    }
    706716#endif
  • trunk/src/VBox/VMM/VMMInternal.h

    r23487 r24582  
    269269    /** Whether log flushing has been disabled or not. */
    270270    bool                        fRCLoggerFlushingDisabled;
    271     bool                        afAlignment[7]; /**< Alignment padding. */
     271    bool                        afAlignment[6]; /**< Alignment padding. */
    272272    /** @} */
     273
     274    /** Whether the stack guard pages have been stationed or not. */
     275    bool                        fStackGuardsStationed;
    273276
    274277    /** The EMT yield timer. */
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r23558 r24582  
    915915    GEN_CHECK_OFF(VMM, cbRCLogger);
    916916    GEN_CHECK_OFF(VMM, fRCLoggerFlushingDisabled);
     917    GEN_CHECK_OFF(VMM, fStackGuardsStationed);
    917918    GEN_CHECK_OFF(VMM, pYieldTimer);
    918919    GEN_CHECK_OFF(VMM, cYieldResumeMillies);
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