copyvirtualspace.c
vmm/vmm.h
sys/kern_sysctl.h
ubixos/spinlock.h
ubixos/kpanic.h
string.h
sys/thread.h
ubixos/kpanic.h
ubixos/spinlock.h
ubixos/types.h
sys/_types.h
vmm/paging.h
string.h
sys/kern_sysctl.h
vmm/vmm.h
sys/sysproto.h
sys/signal.h
src/sys/vmm/copyvirtualspace.c
void * void* vmmCopyVirtualSpace (pidType pid) vmmCopyVirtualSpace pidType pid adjustCowCounter cvsSpinLock kpanic memset PAGE_COW PAGE_DEFAULT PAGE_STACK pageEntries parentPageDirAddr spinLock spinUnlock tablesBaseAddress vmm_getPhysicalAddr vmmGetFreeKernelPage vmmUnmapPage x1 x1000 fork_copyProcess
spinLock_t spinLock_t cvsSpinLock cvsSpinLock SPIN_LOCK_INITIALIZER vmmCopyVirtualSpace

    /*****************************************************************************************
    Copyright(c)2002-2004TheUbixOSProject
    Allrightsreserved.

    Redistributionanduseinsourceandbinaryforms,withorwithoutmodification,are
    permittedprovidedthatthefollowingconditionsaremet:

    Redistributionsofsourcecodemustretaintheabovecopyrightnotice,thislistof
    conditions,thefollowingdisclaimerandthelistofauthors.Redistributionsinbinary
    formmustreproducetheabovecopyrightnotice,thislistofconditions,thefollowing
    disclaimerandthelistofauthorsinthedocumentationand/orothermaterialsprovided
    withthedistribution.NeitherthenameoftheUbixOSProjectnorthenamesofits
    contributorsmaybeusedtoendorseorpromoteproductsderivedfromthissoftware
    withoutspecificpriorwrittenpermission.

    THISSOFTWAREISPROVIDEDBYTHECOPYRIGHTHOLDERSANDCONTRIBUTORS"ASIS"ANDANY
    EXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THEIMPLIEDWARRANTIESOF
    MERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSEAREDISCLAIMED.INNOEVENTSHALL
    THECOPYRIGHTOWNERORCONTRIBUTORSBELIABLEFORANYDIRECT,INDIRECT,INCIDENTAL,
    SPECIAL,EXEMPLARY,ORCONSEQUENTIALDAMAGES(INCLUDING,BUTNOTLIMITEDTO,PROCUREMENT
    OFSUBSTITUTEGOODSORSERVICES;LOSSOFUSE,DATA,ORPROFITS;ORBUSINESSINTERRUPTION)
    HOWEVERCAUSEDANDONANYTHEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,OR
    TORT(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUTOFTHEUSEOFTHIS
    SOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGE.

    $Id: copyvirtualspace_8c.xml 88 2016-01-12 00:11:29Z reddawg $

    *****************************************************************************************/

    #include<vmm/vmm.h>
    #include<sys/kern_sysctl.h>
    #include<ubixos/spinlock.h>
    #include<ubixos/kpanic.h>
    #include<string.h>

    staticspinLock_tcvsSpinLock=SPIN_LOCK_INITIALIZER;

    /************************************************************************

    Function:void*vmmCopyVirtualSpace(pidTypepid);

    Description:CreatesACopyOfAVirtualSpaceAndSetAllNONKernel
    SpaceToCOWForAForkThisWillAlsoAlterTheParents
    VMSpaceToMakeThatCOWAsWell

    Notes:

    08/02/02-AddedPassingOfpidTypepidSoWeCanBetterKeepTrackOf
    WhichTaskHasWhichPhysicalPages

    ************************************************************************/
    void*
    vmmCopyVirtualSpace(pidTypepid)
    {
    void*newPageDirectoryAddress=0x0;
    uInt32*parentPageDirectory=0x0,*newPageDirectory=0x0;
    uInt32*parentPageTable=0x0,*newPageTable=0x0;
    uInt32*parentStackPage=0x0,*newStackPage=0x0;
    uInt16x=0,i=0,s=0;

    spinLock(&cvsSpinLock);

    /*SetAddressOfParentPageDirectory*/
    parentPageDirectory=(uInt32*)parentPageDirAddr;
    /*AllocateANewPageForTheNewPageDirectory*/
    if((newPageDirectory=(uInt32*)vmmGetFreeKernelPage(pid,1))==0x0)
    kpanic("Error:newPageDirectory==NULL,File:%s,Line:%i\n",__FILE__,__LINE__);

    /*SetnewPageDirectoryAddressToTheNewlyCreatedPageDirectoriesPage*/
    newPageDirectoryAddress=(void*)vmm_getPhysicalAddr((uInt32)newPageDirectory);

    /*FirstSetUpAFlushedPageDirectory*/
    memset(newPageDirectory,0x0,0x1000);

    /*MapTheTop1GBRegionOfTheVMSpace*/
    for(x=768;x<pageEntries;x++){
    newPageDirectory[x]=parentPageDirectory[x];
    }

    /*
    *NowForTheFunStuffForPageTables1-766WeMustMapTheseAndSet
    *ThePermissionsOnEveryMappedPagesToCOWThisWillConserveMemory
    *BecauseTheTwoVMSpacesWillBeSharingSomePages
    */
    for(x=0x1;x<=766;x++){
    /*IfPageTableExistsMapIt*/
    if(parentPageDirectory[x]!=0){
    /*SetParentToPropperPageTable*/
    parentPageTable=(uInt32*)(tablesBaseAddress+(0x1000*x));
    /*AllocateANewPageTable*/
    if((newPageTable=(uInt32*)vmmGetFreeKernelPage(pid,1))==0x0)
    kpanic("Error:newPageTable==NULL,File:%s,Line:%i\n",__FILE__,__LINE__);

    /*SetParentAndNewPagesToCOW*/
    for(i=0;i<pageEntries;i++){

    /*IfPageIsMapped*/
    if((parentPageTable[i]&0xFFFFF000)!=0x0){
    /*CheckToSeeIfItsAStackPage*/
    if(((uInt32)parentPageTable[i]&PAGE_STACK)==PAGE_STACK){
    /*AllocANewPageForThisStackPage*/
    if((newStackPage=(uInt32*)vmmGetFreeKernelPage(pid,1))==0x0)
    kpanic("Error:newStackPage==NULL,File:%s,Line:%i\n",__FILE__,__LINE__);

    /*SetPointerToParentsStackPage*/
    parentStackPage=(uInt32*)(((1024*4096)*x)+(4096*i));

    /*CopyTheTackByteForByte(IShouldFindAFasterWay)*/
    for(s=0x0;s<pageEntries;s++){
    newStackPage[s]=parentStackPage[s];
    }
    /*InsertNewStackIntoPageTable*/
    newPageTable[i]=(vmm_getPhysicalAddr((uInt32)newStackPage)|PAGE_DEFAULT|PAGE_STACK);
    /*UnmapFromKernelSpace*/
    vmmUnmapPage((uInt32)newStackPage,1);
    }
    else{
    /*SetPageToCOWInParentAndChildSpace*/
    newPageTable[i]=(((uInt32)parentPageTable[i]&0xFFFFF000)|(PAGE_DEFAULT|PAGE_COW));
    /*IncrementTheCOWCounterForThisPage*/
    if(((uInt32)parentPageTable[i]&PAGE_COW)==PAGE_COW){
    adjustCowCounter(((uInt32)parentPageTable[i]&0xFFFFF000),1);
    }
    else{
    adjustCowCounter(((uInt32)parentPageTable[i]&0xFFFFF000),2);
    parentPageTable[i]=newPageTable[i];
    }
    }
    }
    else{
    newPageTable[i]=(uInt32)0x0;
    }
    }

    /*PutNewPageTableIntoNewPageDirectory*/
    newPageDirectory[x]=(vmm_getPhysicalAddr((uInt32)newPageTable)|PAGE_DEFAULT);
    /*UnmapPageFromKernelSpaceButKeepItMarkedAsNotAvail*/
    vmmUnmapPage((uInt32)newPageTable,1);
    }else{
    newPageDirectory[x]=(uInt32)0x0;
    }
    }
    /*
    *AllocateANewPageForTheTheFirstPageTableWhereWeWillMapThe
    *LowerRegion
    */
    if((newPageTable=(uInt32*)vmmGetFreeKernelPage(pid,1))==0x0)
    kpanic("Error:newPageTable==NULL,File:%s,Line:%i\n",__FILE__,__LINE__);

    /*FlushThePageFromGarbageInMemory*/
    memset(newPageTable,0x0,0x1000);

    /*MapThisIntoThePageDirectory*/
    newPageDirectory[0]=(vmm_getPhysicalAddr((uInt32)newPageTable)|PAGE_DEFAULT);
    /*SetAddressOfParentsPageTable*/
    parentPageTable=(uInt32*)tablesBaseAddress;
    /*MapTheFirst1MBWorthOfPages*/
    for(x=0;x<(pageEntries/4);x++){
    newPageTable[x]=parentPageTable[x];
    }
    /*MapTheNext3MBWorthOfPagesButMakeThemCOW*/
    for(x=(pageEntries/4)+1;x<pageEntries;x++){
    /*IfPageIsAvaiableMapIt*/
    if((parentPageTable[x]&0xFFFFF000)!=0x0){
    /*SetPagesToCOW*/
    newPageTable[x]=(((uInt32)parentPageTable[x]&0xFFFFF000)|(PAGE_DEFAULT|PAGE_COW));
    /*IncrementTheCOWCounterForThisPage*/
    if(((uInt32)parentPageTable[x]&PAGE_COW)==PAGE_COW){
    adjustCowCounter(((uInt32)parentPageTable[x]&0xFFFFF000),1);
    }else{
    adjustCowCounter(((uInt32)parentPageTable[x]&0xFFFFF000),2);
    parentPageTable[x]=newPageTable[x];
    }
    }else{
    newPageTable[x]=(uInt32)0x0;
    }
    }
    /*SetVirtualMappingForPageDirectory*/
    newPageTable[256]=(vmm_getPhysicalAddr((uInt32)newPageDirectory)|PAGE_DEFAULT);

    /*
    *NowTheFunStuffBuildTheInitialVirtualPageSpaceSoWeDon'tHave
    *ToWorryAboutMappingThemInLaterHowEverI'mConcernedThisMay
    *BecomeASecurityIssue
    */
    /*FirstLetsUnmapThePreviouslyAllocatedPageTable*/
    vmmUnmapPage((uInt32)newPageTable,1);
    /*AllocateANewPageTable*/
    if((newPageTable=(uInt32*)vmmGetFreeKernelPage(pid,1))==0x0)
    kpanic("Error:newPageTable==NULL,File:%s,Line:%i\n",__FILE__,__LINE__);
    /*FirstSetOurPageDirectoryToContainThis*/
    newPageDirectory[767]=vmm_getPhysicalAddr((uInt32)newPageTable)|PAGE_DEFAULT;
    /*NowLetsBuildThePageTable*/
    for(x=0;x<pageEntries;x++){
    newPageTable[x]=newPageDirectory[x];
    }
    /*NowWeAreDoneSoLetsUnmapThisPage*/
    vmmUnmapPage((uInt32)newPageTable,1);
    /*NowWeAreDoneWithThePageDirectorySoLetsUnmapThatToo*/
    vmmUnmapPage((uInt32)newPageDirectory,1);

    spinUnlock(&cvsSpinLock);

    /*ReturnPhysicalAddressOfPageDirectory*/
    return(newPageDirectoryAddress);
    }

    /***
    $Log: copyvirtualspace_8c.xml,v $
    Revision 1.6  2006/12/19 14:12:50  reddawg
    rtld-elf almost workign

    Revision1.42006/12/0514:10:21reddawg
    WorkignDistro

    Revision1.32006/12/0105:12:35reddawg
    We'realmostthere...:)

    Revision1.22006/11/0619:10:12reddawg
    LotsOfUpdates...Stillhavingissueswithbrk();

    Revision1.1.1.12006/06/0112:46:13reddawg
    ubix2

    Revision1.22005/10/1200:13:38reddawg
    Removed

    Revision1.1.1.12005/09/2617:24:49reddawg
    nomessage

    Revision1.72004/07/2815:05:43reddawg
    Major:
    Pagesnowhavestrictsecurityenforcement.
    Manynulldereferenceshavebeenresolved.
    Whenappsloadedpermissionssetforpagesrwandro

    Revision1.62004/07/2619:15:49reddawg
    testcode,fixesandthelike

    Revision1.52004/07/2506:04:00reddawg
    Lastofmyfixesforthemorning

    Revision1.42004/07/2022:29:55reddawg
    assert:remadeassert

    Revision1.32004/07/1901:58:12reddawg
    vmmCopyVirtualSpace:cleaneduponefullpagememoryleakwewerestillusingoldsysIDoverpid

    Revision1.22004/06/1512:35:05reddawg
    CleanedUp

    Revision1.1.1.12004/04/1512:06:51reddawg
    UbixOSv1.0

    Revision1.142004/04/1316:36:34reddawg
    Changedourcopyright,itisallnowunderaBSD-Stylelicense

    END
    ***/