source: trunk/kernel/mm/vseg.c @ 625

Last change on this file since 625 was 625, checked in by alain, 2 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 6.5 KB
Line 
1/*
2 * vseg.c - virtual segment (vseg) related operations
3 *
4 * Authors   Ghassan Almaless (2008,2009,2010,2011, 2012)
5 *           Mohamed Lamine Karaoui (2015)
6 *           Alain Greiner (2016,2017,2018,2019)
7 *
8 * Copyright (c) UPMC Sorbonne Universites
9 *
10 * This file is part of ALMOS-MKH.
11 *
12 * ALMOS-MKH is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 2.0 of the License.
15 *
16 * ALMOS-MKH is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <hal_kernel_types.h>
27#include <hal_special.h>
28#include <hal_remote.h>
29#include <list.h>
30#include <errno.h>
31#include <printk.h>
32#include <bits.h>
33#include <thread.h>
34#include <process.h>
35#include <ppm.h>
36#include <mapper.h>
37#include <vfs.h>
38#include <page.h>
39#include <vmm.h>
40#include <kmem.h>
41#include <vseg.h>
42
43////////////////////////////////////////////////////////////////////////////////////////
44//   global variables for display / must be consistent with enum in "vseg.h"
45////////////////////////////////////////////////////////////////////////////////////////
46
47
48//////////////////////////////////////////
49char * vseg_type_str( uint32_t vseg_type )
50{
51        if     ( vseg_type == VSEG_TYPE_CODE   ) return "CODE";
52        else if( vseg_type == VSEG_TYPE_DATA   ) return "DATA";
53        else if( vseg_type == VSEG_TYPE_STACK  ) return "STAK";
54        else if( vseg_type == VSEG_TYPE_ANON   ) return "ANON";
55        else if( vseg_type == VSEG_TYPE_FILE   ) return "FILE";
56        else if( vseg_type == VSEG_TYPE_REMOTE ) return "REMO";
57        else if( vseg_type == VSEG_TYPE_KCODE  ) return "KCOD";
58        else if( vseg_type == VSEG_TYPE_KDATA  ) return "KDAT";
59        else if( vseg_type == VSEG_TYPE_KDEV   ) return "KDEV";
60    else                                     return "undefined";
61}
62
63///////////////////////////
64vseg_t * vseg_alloc( void )
65{
66    kmem_req_t   req;
67
68    req.type  = KMEM_VSEG;
69        req.size  = sizeof(vseg_t);
70        req.flags = AF_KERNEL;
71
72    return (vseg_t *)kmem_alloc( &req );
73}
74
75///////////////////////////////
76void vseg_free( vseg_t * vseg )
77{
78    kmem_req_t  req;
79
80        req.type = KMEM_VSEG;
81        req.ptr  = vseg;
82        kmem_free( &req );
83}
84
85///////////////////////////////////
86void vseg_init( vseg_t      * vseg,
87                vseg_type_t   type,
88                    intptr_t      base,
89                uint32_t      size,
90                vpn_t         vpn_base,
91                vpn_t         vpn_size,
92                        uint32_t      file_offset,
93                uint32_t      file_size,
94                xptr_t        mapper_xp,
95                cxy_t         cxy )
96{
97    vseg->type        = type;
98        vseg->min         = base;
99        vseg->max         = base + size;
100    vseg->vpn_base    = vpn_base;
101        vseg->vpn_size    = vpn_size;
102    vseg->file_offset = file_offset;
103    vseg->file_size   = file_size;
104        vseg->mapper_xp   = mapper_xp;
105    vseg->cxy         = cxy;
106
107    // set vseg flags depending on type
108        if     ( type == VSEG_TYPE_CODE )
109    {
110        vseg->flags = VSEG_USER    |
111                      VSEG_EXEC    |
112                      VSEG_CACHE   |
113                      VSEG_PRIVATE ;
114    }
115    else if( type == VSEG_TYPE_STACK )
116    {
117        vseg->flags = VSEG_USER    |
118                      VSEG_WRITE   |
119                      VSEG_CACHE   |
120                      VSEG_PRIVATE ;
121    }
122    else if( type == VSEG_TYPE_DATA )
123    {
124        vseg->flags = VSEG_USER    |
125                      VSEG_WRITE   |
126                      VSEG_CACHE   |
127                      VSEG_DISTRIB ;
128    }
129    else if( type == VSEG_TYPE_REMOTE )
130    {
131        vseg->flags = VSEG_USER    |
132                      VSEG_WRITE   |
133                      VSEG_CACHE   ;
134    }
135    else if( type == VSEG_TYPE_ANON )
136    {
137        vseg->flags = VSEG_USER    |
138                      VSEG_WRITE   |
139                      VSEG_CACHE; 
140    }
141    else if( type == VSEG_TYPE_FILE )
142    {
143        vseg->flags = VSEG_USER    |
144                      VSEG_WRITE   |
145                      VSEG_CACHE   ;
146    }
147    else if( type == VSEG_TYPE_KCODE )
148    {
149        vseg->flags = VSEG_EXEC    |
150                      VSEG_CACHE   |
151                      VSEG_PRIVATE ;
152    }
153    else if( type == VSEG_TYPE_KDATA )
154    {
155        vseg->flags = VSEG_CACHE   |
156                      VSEG_WRITE   ;
157    }
158    else if( type == VSEG_TYPE_KDEV )
159    {
160        vseg->flags = VSEG_WRITE   ;
161    }
162    else
163    {
164            assert( false , "illegal vseg type\n" );
165    }
166
167}  // end vseg_init()
168
169//////////////////////////////////////////
170void vseg_init_from_ref( vseg_t    * vseg,
171                         xptr_t      ref_xp )
172{
173    // get remote vseg cluster and pointer
174    cxy_t    cxy = (cxy_t   )GET_CXY( ref_xp );
175    vseg_t * ptr = (vseg_t *)GET_PTR( ref_xp );
176
177    // initialize vseg with remote_read access
178    vseg->type        =           hal_remote_l32( XPTR( cxy , &ptr->type        ) );
179    vseg->min         = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->min         ) );
180    vseg->max         = (intptr_t)hal_remote_lpt( XPTR( cxy , &ptr->max         ) );
181    vseg->vpn_base    =           hal_remote_l32( XPTR( cxy , &ptr->vpn_base    ) );
182    vseg->vpn_size    =           hal_remote_l32( XPTR( cxy , &ptr->vpn_size    ) );
183    vseg->flags       =           hal_remote_l32( XPTR( cxy , &ptr->flags       ) );
184    vseg->file_offset =           hal_remote_l32( XPTR( cxy , &ptr->file_offset ) );
185    vseg->file_size   =           hal_remote_l32( XPTR( cxy , &ptr->file_size   ) );
186        vseg->mapper_xp   = (xptr_t)  hal_remote_l64( XPTR( cxy , &ptr->mapper_xp   ) );
187
188    switch (vseg->type)
189    {
190        case VSEG_TYPE_DATA:      // unused
191        {
192            vseg->cxy = 0xffff;
193            break;
194        }
195        case VSEG_TYPE_CODE:      // always local
196        case VSEG_TYPE_STACK: 
197        case VSEG_TYPE_KCODE:
198        {
199            vseg->cxy = local_cxy;
200            break;
201        }
202        case VSEG_TYPE_ANON:      // intrinsic
203        case VSEG_TYPE_FILE:
204        case VSEG_TYPE_REMOTE: 
205        case VSEG_TYPE_KDEV:
206        case VSEG_TYPE_KDATA:
207        {
208            vseg->cxy = (cxy_t) hal_remote_l32( XPTR(cxy, &ptr->cxy) );
209            break;
210        }
211        default: 
212        {
213            assert( false, "Illegal vseg type" );
214            break;
215        }
216    }
217}
218
219
Note: See TracBrowser for help on using the repository browser.