Changeset 23 for trunk/kernel/mm/vmm.c


Ignore:
Timestamp:
Jun 18, 2017, 10:06:41 PM (7 years ago)
Author:
alain
Message:

Introduce syscalls.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/mm/vmm.c

    r21 r23  
    2929#include <hal_gpt.h>
    3030#include <printk.h>
     31#include <memcpy.h>
    3132#include <rwlock.h>
    3233#include <list.h>
     
    9495
    9596    // initialize local list of vsegs and radix-tree
     97    vmm->vsegs_nr = 0;
    9698        list_root_init( &vmm->vsegs_root );
    97     vmm->vsegs_nr = 0;
    9899    error = grdxt_init( &vmm->grdxt,
    99100                        CONFIG_VMM_GRDXT_W1,
     
    182183
    183184}  // end vmm_init()
     185
     186//////////////////////////////////////////
     187error_t vmm_copy( process_t * dst_process,
     188                  process_t * src_process )
     189{
     190    error_t error;
     191
     192    vmm_t * src_vmm = &src_process->vmm;
     193    vmm_t * dst_vmm = &dst_process->vmm;
     194
     195    // take the src_vmm vsegs_lock
     196    rwlock_wr_lock( &src_vmm->vsegs_lock );
     197
     198    // initialise dst_vmm vsegs_lock
     199    rwlock_init( &dst_vmm->vsegs_lock );
     200
     201    // initialise the dst_vmm vsegs list and the radix tree
     202    dst_vmm->vsegs_nr = 0;
     203    list_root_init( &dst_vmm->vsegs_root );
     204    error = grdxt_init( &dst_vmm->grdxt,
     205                        CONFIG_VMM_GRDXT_W1,
     206                        CONFIG_VMM_GRDXT_W2,
     207                        CONFIG_VMM_GRDXT_W3 );
     208    if( error )
     209    {
     210        printk("\n[ERROR] in %s : cannot initialise radix tree for process %x\n",
     211               __FUNCTION__ , dst_process->pid );
     212        return ENOMEM;
     213    }
     214
     215    // loop on src_vmm list of vsegs to create
     216    // and register vsegs copies in dst_vmm
     217    list_entry_t * iter;
     218    vseg_t       * src_vseg;
     219    vseg_t       * dst_vseg;
     220    LIST_FOREACH( &src_vmm->vsegs_root , iter )
     221    {
     222        // get pointer on current src_vseg
     223        src_vseg = LIST_ELEMENT( iter , vseg_t , list );
     224
     225        // allocate memory for a new dst_vseg
     226        dst_vseg = vseg_alloc();
     227
     228        if( dst_vseg == NULL )
     229        {
     230            // release all allocated vsegs
     231            LIST_FOREACH( &dst_vmm->vsegs_root , iter )
     232            {
     233                dst_vseg = LIST_ELEMENT( iter , vseg_t , list );
     234                vseg_free( dst_vseg );
     235            }
     236            return ENOMEM;
     237        }
     238
     239        // copy src_vseg to dst_vseg
     240        vseg_init_from_ref( dst_vseg , XPTR( local_cxy , src_vseg ) );
     241
     242        // register dst_vseg in dst_vmm
     243        vseg_attach( dst_vmm , dst_vseg );
     244    }
     245
     246    // release the src_vmm vsegs_lock
     247    rwlock_wr_unlock( &src_vmm->vsegs_lock );
     248
     249    // initialize generic page table
     250    error = hal_gpt_create( &dst_vmm->gpt );
     251
     252    if( error )
     253    {
     254        printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );
     255        return ENOMEM;
     256    }
     257
     258    // initialize STACK allocator
     259    dst_vmm->stack_mgr.bitmap   = 0;
     260    dst_vmm->stack_mgr.vpn_base = CONFIG_VMM_STACK_BASE;
     261
     262    // initialize MMAP allocator
     263    dst_vmm->mmap_mgr.vpn_base        = CONFIG_VMM_MMAP_BASE;
     264    dst_vmm->mmap_mgr.vpn_size        = CONFIG_VMM_STACK_BASE - CONFIG_VMM_MMAP_BASE;
     265    dst_vmm->mmap_mgr.first_free_vpn  = CONFIG_VMM_MMAP_BASE;
     266    uint32_t i;
     267    for( i = 0 ; i < 32 ; i++ ) list_root_init( &dst_vmm->mmap_mgr.zombi_list[i] );
     268
     269    // initialise instrumentation counters
     270        dst_vmm->pgfault_nr    = 0;
     271        dst_vmm->u_err_nr      = 0;
     272        dst_vmm->m_err_nr      = 0;
     273
     274    // copy base addresses
     275    dst_vmm->kent_vpn_base = src_vmm->kent_vpn_base;
     276    dst_vmm->args_vpn_base = src_vmm->args_vpn_base;
     277    dst_vmm->envs_vpn_base = src_vmm->envs_vpn_base;
     278    dst_vmm->heap_vpn_base = src_vmm->heap_vpn_base;
     279    dst_vmm->code_vpn_base = src_vmm->code_vpn_base;
     280    dst_vmm->data_vpn_base = src_vmm->data_vpn_base;
     281
     282    dst_vmm->entry_point   = src_vmm->entry_point;
     283
     284    // HEAP TODO : new heap for child ???
     285    dst_vmm->heap_vseg     = src_vmm->heap_vseg;
     286
     287    // initialize generic page table
     288    error = hal_gpt_create( &dst_vmm->gpt );
     289
     290    if( error )
     291    {
     292        printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ );
     293        return ENOMEM;
     294    }
     295
     296    // copy GPT content from src_vmm to dst_vmm, activating "Copy-On-Write"
     297    // TODO register Copy-On_Write in page descriptors
     298    bool_t cow = true;
     299    hal_gpt_copy( &dst_vmm->gpt , &src_vmm->gpt , cow );
     300
     301    hal_wbflush();
     302
     303    return 0;
     304
     305}  // end vmm_copy()
    184306
    185307///////////////////////////////////////
     
    659781    error_t   error;
    660782
    661     // this function must be called by in the reference cluster
    662     if( process->is_ref == false );
     783    // this function must be called by a thread running in the reference cluster
     784    if( GET_CXY( process->ref_xp ) != local_cxy );
    663785    {
    664786        printk("\n[PANIC] in %s : not called in the reference cluster\n", __FUNCTION__ );
     
    796918                           paddr_t * paddr )
    797919{
    798     uint32_t vaddr = (uint32_t)ptr;
    799 
    800     thread_t  * this    = CURRENT_THREAD;
    801     process_t * process = this->process;
     920    process_t * process = CURRENT_THREAD->process;
    802921
    803922    if( ident )  // identity mapping
    804923    {
    805         *paddr = (paddr_t)PADDR( local_cxy , vaddr );
     924        *paddr = (paddr_t)PADDR( local_cxy , (lpa_t)ptr );
    806925        return 0;
    807926    }
     
    814933    uint32_t offset;
    815934
    816     vpn    = (vpn_t)( vaddr >> CONFIG_PPM_PAGE_SHIFT );
    817     offset = (uint32_t)( vaddr & CONFIG_PPM_PAGE_MASK );
    818 
    819     if( process->is_ref )   // calling process is reference process
     935    vpn    = (vpn_t)( (intptr_t)ptr >> CONFIG_PPM_PAGE_SHIFT );
     936    offset = (uint32_t)( ((intptr_t)ptr) & CONFIG_PPM_PAGE_MASK );
     937
     938    if( local_cxy == GET_CXY( process->ref_xp) )   // calling process is reference process
    820939    {
    821940        error = vmm_get_pte( process, vpn , &attr , &ppn );
    822941    }
    823     else                    // use a RPC
     942    else                                           // use a RPC
    824943    {
    825944        cxy_t       ref_cxy = GET_CXY( process->ref_xp );
     
    828947    }
    829948
    830     if( error )
    831     {
    832         printk("\n[ERROR] in %s : cannot get physical address for vaddr = %x\n",
    833                __FUNCTION__ , vaddr );
    834         return error;
    835     }
    836 
    837     // return paddr
     949    // set paddr
    838950    *paddr = (((paddr_t)ppn) << CONFIG_PPM_PAGE_SHIFT) | offset;
    839     return 0;
     951
     952    return error;
    840953
    841954}  // end vmm_v2p_translate()
     955
     956//////////////////////////////////////////////
    842957
    843958
Note: See TracChangeset for help on using the changeset viewer.