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


Ignore:
Timestamp:
Mar 6, 2019, 4:37:15 PM (5 years ago)
Author:
alain
Message:

Introduce three new types of vsegs (KCODE,KDATA,KDEV)
to map the kernel vsegs in the process VSL and GPT.
This now used by both the TSAR and the I86 architectures.

File:
1 edited

Legend:

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

    r621 r623  
    5959{
    6060    error_t   error;
    61     vseg_t  * vseg_kentry;
    6261    vseg_t  * vseg_args;
    6362    vseg_t  * vseg_envs;
     
    9190(CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE)) ,
    9291"STACK zone too small\n");
    93 
    94     // register kentry vseg in VSL
    95     base = CONFIG_VMM_KENTRY_BASE << CONFIG_PPM_PAGE_SHIFT;
    96     size = CONFIG_VMM_KENTRY_SIZE << CONFIG_PPM_PAGE_SHIFT;
    97 
    98     vseg_kentry = vmm_create_vseg( process,
    99                                    VSEG_TYPE_CODE,
    100                                    base,
    101                                    size,
    102                                    0,             // file_offset unused
    103                                    0,             // file_size unused
    104                                    XPTR_NULL,     // mapper_xp unused
    105                                    local_cxy );
    106 
    107     if( vseg_kentry == NULL )
    108     {
    109         printk("\n[ERROR] in %s : cannot register kentry vseg\n", __FUNCTION__ );
    110         return -1;
    111     }
    112 
    113     vmm->kent_vpn_base = base;
    11492
    11593    // register args vseg in VSL
     
    162140
    163141    if( error )
    164     printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ );
     142    {
     143        printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ );
     144        return -1;
     145    }
    165146
    166147    // initialize GPT lock
    167148    remote_rwlock_init( XPTR( local_cxy , &vmm->gpt_lock ) , LOCK_VMM_GPT );
    168149
    169     // architecture specic GPT initialisation
    170     // (For TSAR, identity map the kentry_vseg)
    171     error = hal_vmm_init( vmm );
    172 
    173     if( error )
    174     printk("\n[ERROR] in %s : cannot initialize GPT\n", __FUNCTION__ );
     150    // update process VMM with kernel vsegs
     151    error = hal_vmm_kernel_update( process );
     152
     153    if( error )
     154    {
     155        printk("\n[ERROR] in %s : cannot update GPT for kernel vsegs\n", __FUNCTION__ );
     156        return -1;
     157    }
    175158
    176159    // initialize STACK allocator
     
    326309    }
    327310
    328     // release physical memory allocated for vseg descriptor if no MMAP type
    329     if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) )
     311    // release physical memory allocated for vseg if no MMAP and no kernel type
     312    if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) &&
     313        (type != VSEG_TYPE_KCODE) && (type != VSEG_TYPE_KDATA) && (type != VSEG_TYPE_KDEV) )
    330314    {
    331315        vseg_free( vseg );
     
    606590    child_vmm->vsegs_nr = 0;
    607591
    608     // create child GPT
     592    // create the child GPT
    609593    error = hal_gpt_create( &child_vmm->gpt );
    610594
     
    639623#endif
    640624
    641         // all parent vsegs - but STACK - must be copied in child VSL
    642         if( type != VSEG_TYPE_STACK )
     625        // all parent vsegs - but STACK and kernel vsegs - must be copied in child VSL
     626        if( (type != VSEG_TYPE_STACK) && (type != VSEG_TYPE_KCODE) &&
     627            (type != VSEG_TYPE_KDATA) && (type != VSEG_TYPE_KDEV) )
    643628        {
    644629            // allocate memory for a new child vseg
     
    726711    remote_rwlock_rd_release( parent_lock_xp );
    727712
    728     // initialize child GPT (architecture specic)
    729     // => For TSAR, identity map the kentry_vseg
    730     error = hal_vmm_init( child_vmm );
     713    // update child VMM with kernel vsegs
     714    error = hal_vmm_kernel_update( child_process );
    731715
    732716    if( error )
    733717    {
    734         printk("\n[ERROR] in %s : cannot create GPT\n", __FUNCTION__ );
     718        printk("\n[ERROR] in %s : cannot update child VMM\n", __FUNCTION__ );
    735719        return -1;
    736720    }
     
    10981082        base = vpn_base << CONFIG_PPM_PAGE_SHIFT;
    10991083    }
    1100     else    // VSEG_TYPE_DATA or VSEG_TYPE_CODE
     1084    else    // VSEG_TYPE_DATA, VSEG_TYPE_CODE or KERNEL vseg
    11011085    {
    11021086        uint32_t vpn_min = base >> CONFIG_PPM_PAGE_SHIFT;
     
    11781162    xptr_t      lock_xp;    // extended pointer on lock protecting forks counter
    11791163    uint32_t    forks;      // actual number of pendinf forks
     1164    uint32_t    type;       // vseg type
    11801165
    11811166#if DEBUG_VMM_DELETE_VSEG
     
    11901175    process = cluster_get_local_process_from_pid( pid );
    11911176
    1192     if( process == NULL ) return;
     1177    if( process == NULL )
     1178    {
     1179        printk("\n[ERRORR] in %s : cannot get local process descriptor\n",
     1180        __FUNCTION__ );
     1181        return;
     1182    }
    11931183
    11941184    // get pointers on local process VMM an GPT
     
    11991189    vseg = vmm_vseg_from_vaddr( vmm , vaddr );
    12001190
    1201     if( vseg == NULL ) return;
    1202 
    1203     // loop to invalidate all vseg PTEs in GPT
     1191    if( vseg == NULL )
     1192    {
     1193        printk("\n[ERRORR] in %s : cannot get vseg descriptor\n",
     1194        __FUNCTION__ );
     1195        return;
     1196    }
     1197
     1198    // get relevant vseg infos
     1199    type    = vseg->type;
    12041200    vpn_min = vseg->vpn_base;
    12051201    vpn_max = vpn_min + vseg->vpn_size;
     1202
     1203    // loop to invalidate all vseg PTEs in GPT
    12061204        for( vpn = vpn_min ; vpn < vpn_max ; vpn++ )
    12071205    {
     
    12161214printk("- unmap vpn %x / ppn %x / vseg %s \n" , vpn , ppn, vseg_type_str(vseg->type) );
    12171215#endif
    1218 
    1219 // check small page
    1220 assert( (attr & GPT_SMALL) , "an user vseg must use small pages" );
    1221 
    12221216            // unmap GPT entry in local GPT
    12231217            hal_gpt_reset_pte( gpt , vpn );
    12241218
    1225             // handle pending forks counter if
    1226             // 1) not identity mapped
    1227             // 2) reference cluster
    1228             if( ((vseg->flags & VSEG_IDENT)  == 0) &&
    1229                 (GET_CXY( process->ref_xp ) == local_cxy) )
     1219            // the allocated page is not released to KMEM for kernel vseg
     1220            if( (type != VSEG_TYPE_KCODE) &&
     1221                (type != VSEG_TYPE_KDATA) &&
     1222                (type != VSEG_TYPE_KDEV ) )
    12301223            {
     1224
     1225// FIXME This code must be completely re-written, as the actual release must depend on
     1226// - the vseg type
     1227// - the reference cluster
     1228// - the page refcount and/or the forks counter
     1229
    12311230                // get extended pointer on physical page descriptor
    12321231                page_xp  = ppm_ppn2page( ppn );
     
    12381237                lock_xp  = XPTR( page_cxy , &page_ptr->lock );
    12391238
     1239                // get the lock protecting the page
    12401240                remote_busylock_acquire( lock_xp );
     1241
    12411242                // get pending forks counter
    12421243                forks = hal_remote_l32( forks_xp );
     1244
    12431245                if( forks )  // decrement pending forks counter
    12441246                {
     
    12631265#endif
    12641266                }
     1267
     1268                // release the lock protecting the page
    12651269                remote_busylock_release( lock_xp );
    12661270            }
     
    13111315    // return failure
    13121316    remote_rwlock_rd_release( lock_xp );
     1317
    13131318    return NULL;
    13141319
     
    13251330    vpn_t     vpn_max;
    13261331
     1332#if DEBUG_VMM_RESIZE_VSEG
     1333uint32_t   cycle = (uint32_t)hal_get_cycles();
     1334thread_t * this  = CURRENT_THREAD;
     1335if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1336printk("\n[%s] thread[%x,%x] enter / process %x / base %x / size %d / cycle %d\n",
     1337__FUNCTION__, this->process->pid, this->trdid, process->pid, base, size, cycle );
     1338#endif
     1339
    13271340    // get pointer on process VMM
    13281341    vmm_t * vmm = &process->vmm;
     
    13341347        vseg_t * vseg = vmm_vseg_from_vaddr( vmm , base );
    13351348
    1336         if( vseg == NULL)  return EINVAL;
    1337 
    1338     // get extended pointer on VSL lock
    1339     xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock );
    1340 
    1341     // get lock protecting VSL
    1342         remote_rwlock_wr_acquire( lock_xp );
    1343 
     1349        if( vseg == NULL)
     1350    {
     1351        printk("\n[ERROR] in %s : vseg(%x,%d) not found\n",
     1352        __FUNCTION__, base , size );
     1353        return -1;
     1354    }
     1355
     1356    // resize depends on unmapped region base and size
    13441357        if( (vseg->min > addr_min) || (vseg->max < addr_max) )        // not included in vseg
    13451358    {
     1359        printk("\n[ERROR] in %s : unmapped region[%x->%x[ not included in vseg[%x->%x[\n",
     1360        __FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
     1361
    13461362        error = -1;
    13471363    }
    13481364        else if( (vseg->min == addr_min) && (vseg->max == addr_max) )  // vseg must be deleted
    13491365    {
     1366
     1367#if( DEBUG_VMM_RESIZE_VSEG & 1 )
     1368if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1369printk("\n[%s] unmapped region[%x->%x[ equal vseg[%x->%x[\n",
     1370__FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
     1371#endif
    13501372        vmm_delete_vseg( process->pid , vseg->min );
     1373
     1374#if( DEBUG_VMM_RESIZE_VSEG & 1 )
     1375if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1376printk("\n[%s] thread[%x,%x] deleted vseg\n",
     1377__FUNCTION__, this->process->pid, this->trdid );
     1378#endif
    13511379        error = 0;
    13521380    }
    13531381        else if( vseg->min == addr_min )                               // vseg must be resized
    13541382    {
    1355         // update vseg base address
     1383
     1384#if( DEBUG_VMM_RESIZE_VSEG & 1 )
     1385if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1386printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n",
     1387__FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
     1388#endif
     1389        // update vseg min address
    13561390        vseg->min = addr_max;
    13571391
     
    13611395        vseg->vpn_base = vpn_min;
    13621396        vseg->vpn_size = vpn_max - vpn_min + 1;
     1397
     1398#if( DEBUG_VMM_RESIZE_VSEG & 1 )
     1399if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1400printk("\n[%s] thread[%x,%x] changed vseg_min\n",
     1401__FUNCTION__, this->process->pid, this->trdid );
     1402#endif
    13631403        error = 0;
    13641404    }
    13651405        else if( vseg->max == addr_max )                              // vseg must be resized
    13661406    {
     1407
     1408#if( DEBUG_VMM_RESIZE_VSEG & 1 )
     1409if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1410printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n",
     1411__FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
     1412#endif
    13671413        // update vseg max address
    13681414        vseg->max = addr_min;
     
    13731419        vseg->vpn_base = vpn_min;
    13741420        vseg->vpn_size = vpn_max - vpn_min + 1;
     1421
     1422#if( DEBUG_VMM_RESIZE_VSEG & 1 )
     1423if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1424printk("\n[%s] thread[%x,%x] changed vseg_max\n",
     1425__FUNCTION__, this->process->pid, this->trdid );
     1426#endif
    13751427        error = 0;
     1428
    13761429    }
    13771430    else                                                          // vseg cut in three regions
    13781431    {
     1432
     1433#if( DEBUG_VMM_RESIZE_VSEG & 1 )
     1434if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1435printk("\n[%s] unmapped region[%x->%x[ included in vseg[%x->%x[\n",
     1436__FUNCTION__, addr_min, addr_max, vseg->min, vseg->max );
     1437#endif
    13791438        // resize existing vseg
    13801439        vseg->max = addr_min;
     
    13961455                               vseg->cxy );
    13971456
    1398         if( new == NULL ) error = EINVAL;
     1457#if( DEBUG_VMM_RESIZE_VSEG & 1 )
     1458if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1459printk("\n[%s] thread[%x,%x] replaced vseg by two smal vsegs\n",
     1460__FUNCTION__, this->process->pid, this->trdid );
     1461#endif
     1462
     1463        if( new == NULL ) error = -1;
    13991464        else              error = 0;
    14001465    }
    14011466
    1402     // release VMM lock
    1403         remote_rwlock_wr_release( lock_xp );
     1467#if DEBUG_VMM_RESIZE_VSEG
     1468if( DEBUG_VMM_RESIZE_VSEG < cycle )
     1469printk("\n[%s] thread[%x,%x] exit / process %x / base %x / size %d / cycle %d\n",
     1470__FUNCTION__, this->process->pid, this->trdid, process->pid, base, size, cycle );
     1471#endif
    14041472
    14051473        return error;
Note: See TracChangeset for help on using the changeset viewer.