Ignore:
Timestamp:
Nov 7, 2017, 3:08:12 PM (7 years ago)
Author:
alain
Message:

First implementation of fork/exec.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/sys_mmap.c

    r23 r407  
    2424
    2525#include <hal_types.h>
     26#include <hal_uspace.h>
     27#include <shared_syscalls.h>
    2628#include <errno.h>
    2729#include <thread.h>
    2830#include <printk.h>
     31#include <mapper.h>
    2932#include <vfs.h>
    3033#include <process.h>
    3134#include <vmm.h>
    3235
    33 ///////////////////////////////////
     36//////////////////////////////////
    3437int sys_mmap( mmap_attr_t * attr )
    3538{
    36     printk("\n[WARNING] function %s not implemented\n", __FUNCTION__ );
    37     return 0;
    38 /*   
    39         error_t err;
    40         uint_t count;
    41         struct thread_s *this;
    42         struct process_s *process;
    43         struct vfs_file_s *file;
    44         mmap_attr_t attr;
    45         size_t isize;
    46         int retval;
     39    vseg_t      * vseg;
     40    cxy_t         vseg_cxy;
     41    vseg_type_t   vseg_type;
     42    mmap_attr_t   k_attr;       // attributes copy in kernel space
     43    xptr_t        mapper_xp;
     44    error_t       error;
     45    paddr_t       paddr;        // unused, but required for user space checking
     46
     47        uint64_t      tm_start;
     48        uint64_t      tm_end;
     49
     50        tm_start = hal_get_cycles();
     51
     52        thread_t    * this    = CURRENT_THREAD;
     53        process_t   * process = this->process;
     54
     55    // check arguments in user space
     56    error = vmm_v2p_translate( false , attr , &paddr );
     57
     58    if ( error )
     59    {
     60        printk("\n[ERROR] in %s : arguments not in used space = %x\n",
     61        __FUNCTION__ , (intptr_t)attr );
     62                this->errno = EINVAL;
     63                return -1;
     64    }
     65
     66    // copy arguments from uspace
     67    hal_copy_from_uspace( &k_attr , attr , sizeof(mmap_attr_t) );
     68
     69    // get fdid, offset, and length arguments
     70    uint32_t fdid   = k_attr.fdid;
     71    uint32_t offset = k_attr.offset;
     72    uint32_t length = k_attr.length;
     73
     74    // get flags
     75    bool_t     map_fixed   = ( (k_attr.flags & MAP_FIXED)   != 0 );
     76    bool_t     map_anon    = ( (k_attr.flags & MAP_ANON)    != 0 );
     77    bool_t     map_remote  = ( (k_attr.flags & MAP_REMOTE)  != 0 );
     78    bool_t     map_shared  = ( (k_attr.flags & MAP_SHARED)  != 0 );
     79    bool_t     map_private = ( (k_attr.flags & MAP_PRIVATE) != 0 );
     80
     81    // MAP_FIXED not supported
     82    if( map_fixed )
     83    {
     84        printk("\n[ERROR] in %s : MAP_FIXED not supported\n", __FUNCTION__ );
     85        this->errno = EINVAL;
     86        return -1;
     87    }
     88
     89    if( map_shared == map_private )
     90    {
     91        printk("\n[ERROR] in %s : MAP_SHARED xor MAP_PRIVATE\n", __FUNCTION__ );
     92        this->errno = EINVAL;
     93        return -1;
     94    }
     95
     96    // FIXME handle Copy_On_Write for MAP_PRIVATE...
     97
     98    // get access rigths
     99    bool_t     prot_read   = ( (k_attr.prot & PROT_READ )   != 0 );
     100    bool_t     prot_write  = ( (k_attr.prot & PROT_WRITE)   != 0 );
     101
     102    // test mmap type : can be FILE / ANON / REMOTE
     103
     104    if( (map_anon == false) && (map_remote == false) )   // FILE
     105    {
     106            // FIXME: handle concurent delete of file by another thread closing it
     107
     108                if( fdid >= CONFIG_PROCESS_FILE_MAX_NR )
     109                {
     110                        printk("\n[ERROR] in %s: bad file descriptor = %d\n", __FUNCTION__ , fdid );
     111            this->errno = EBADFD;
     112            return -1;
     113        }
     114
     115        // get extended pointer on file descriptor
     116        xptr_t file_xp = process_fd_get_xptr( process , fdid );
     117
     118        if( file_xp == XPTR_NULL )
     119        {
     120                        printk("\n[ERROR] in %s: file %d not found\n", __FUNCTION__ , fdid );
     121            this->errno = EBADFD;
     122            return -1;
     123        }
     124
     125        // get file cluster and local pointer
     126        cxy_t        file_cxy = GET_CXY( file_xp );
     127        vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );
     128
     129        // get inode pointer, mapper pointer and file attributes
     130        vfs_inode_t * inode_ptr  = hal_remote_lpt(XPTR(file_cxy , &file_ptr->inode ));
     131        uint32_t      file_attr  = hal_remote_lw (XPTR(file_cxy , &file_ptr->attr  ));
     132        mapper_t    * mapper_ptr = hal_remote_lpt(XPTR(file_cxy , &file_ptr->mapper));
     133
     134        // get file size
     135                uint32_t size = hal_remote_lw( XPTR( file_cxy , &inode_ptr->size ) );
     136
     137        // chek offset and length arguments
     138                if( (offset + length) > size)
     139                {
     140                        printk("\n[ERROR] in %s: offset (%d) + len (%d) >= file's size (%d)\n",
     141                        __FUNCTION__, k_attr.offset, k_attr.length, size );
     142            this->errno = ERANGE;
     143            return -1;
     144                }
     145
     146        // check access rights
     147                if( (prot_read  && !(file_attr & FD_ATTR_READ_ENABLE)) ||
     148                    (prot_write && !(file_attr & FD_ATTR_WRITE_ENABLE)) )
     149                {
     150                        printk("\n[ERROR] in %s: prot = %x / file_attr = %x)\n",
     151                        __FUNCTION__ , k_attr.prot , file_attr );
     152                        this->errno = EACCES;
     153                        return -1;
     154                }
     155
     156                // increment file refcount
     157                vfs_file_count_up( file_xp );
     158
     159        mapper_xp = XPTR( file_cxy , mapper_ptr );
     160        vseg_type = VSEG_TYPE_FILE;
     161        vseg_cxy  = file_cxy;
     162    }
     163    else                                                // ANON or REMOTE
     164    {
     165        // no mapper for ANON or REMOTE
     166        mapper_xp = XPTR_NULL;
     167
     168        if( map_anon )
     169        {
     170            vseg_type = VSEG_TYPE_ANON;
     171            vseg_cxy  = local_cxy;
     172        }
     173        else
     174        {
     175            vseg_type = VSEG_TYPE_REMOTE;
     176            vseg_cxy  = k_attr.fdid;
    47177 
    48         this = current_thread;
    49         process = this->process;
    50         err  = EINVAL;
    51         file = NULL;
    52 
    53         if((err = cpu_copy_from_uspace(&attr, attr, sizeof(mmap_attr_t))))
    54         {
    55                 printk(INFO, "%s: failed, copying from uspace @%x\n",
    56                        __FUNCTION__,
    57                        attr);
    58 
    59                 this->info.errno = EFAULT;
    60                 return (int)VM_FAILED;
    61         }
    62 
    63         if((attr.flags  & VM_REG_HEAP)                     ||
    64            ((attr.flags & VM_REG_PVSH) == VM_REG_PVSH)     ||
    65            ((attr.flags & VM_REG_PVSH) == 0)               ||
    66            (attr.length == 0)                              ||
    67            (attr.offset & PMM_PAGE_MASK)                   ||
    68            ((attr.addr != NULL) && (((uint_t)attr.addr & PMM_PAGE_MASK)          ||
    69                                 (NOT_IN_USPACE(attr.length + (uint_t)attr.addr)) ||
    70                                 (NOT_IN_USPACE((uint_t)attr.addr)) )))
    71         {
    72                 printk(INFO, "%s: failed, we don't like flags (%x), length (%d), or addr (%x)\n",
    73                        __FUNCTION__,
    74                        attr.flags,
    75                        attr.length,
    76                        attr.addr);
    77      
    78                 this->info.errno = EINVAL;
    79                 return (int)VM_FAILED;
    80         }
    81    
    82         if(attr.flags & VM_REG_ANON)
    83         {
    84                 attr.offset = 0;
    85                 attr.addr   = (attr.flags & VM_REG_FIXED) ? attr.addr : NULL;
    86         }
    87         else
    88         {     
    89                 // FIXME: possible concurent delete of file from another bugy thread closing it
    90                 if((attr.fd >= CONFIG_TASK_FILE_MAX_NR) || (process_fd_lookup(process, attr.fd, &file)))
    91                 {
    92                         printk(INFO, "%s: failed, bad file descriptor (%d)\n",
    93                                __FUNCTION__,
    94                                attr.fd);
    95 
    96                         this->info.errno = EBADFD;
    97                         return (int)VM_FAILED;
    98                 }
    99      
    100                 //atomic_add(&file->f_count, 1);
    101                 vfs_file_up(file);//FIXME coalsce access to remote node info
    102      
    103                 //FIXME: does we really to get the size...
    104                 isize = vfs_inode_size_get_remote(file->f_inode.ptr, file->f_inode.cid);
    105                 if((attr.offset + attr.length) > isize)
    106                 {
    107                         printk(INFO, "%s: failed, offset (%d) + len (%d) >= file's size (%d)\n",
    108                                __FUNCTION__,
    109                                attr.offset,
    110                                attr.length,
    111                                isize);
    112 
    113                         this->info.errno = ERANGE;
    114                         goto SYS_MMAP_FILE_ERR;
    115                 }
    116 
    117                 if(((attr.prot & VM_REG_RD) && !(VFS_IS(file->f_flags, VFS_O_RDONLY)))   ||
    118                    ((attr.prot & VM_REG_WR) && !(VFS_IS(file->f_flags, VFS_O_WRONLY)))   ||
    119                    ((attr.prot & VM_REG_WR) && (VFS_IS(file->f_flags, VFS_O_APPEND))))//    ||
    120                         //(!(attr.prot & VM_REG_RD) && (attr.flags & VM_REG_PRIVATE)))
    121                 {
    122                         printk(INFO, "%s: failed, EACCES prot (%x), f_flags (%x)\n",
    123                                __FUNCTION__,
    124                                attr.prot,
    125                                file->f_flags);
    126 
    127                         this->info.errno = EACCES;
    128                         goto SYS_MMAP_FILE_ERR;
    129                 }
    130         }
    131 
    132         retval = (int) vmm_mmap(process,
    133                                 file,
    134                                 attr.addr,
    135                                 attr.length,
    136                                 attr.prot,
    137                                 attr.flags,
    138                                 attr.offset);
    139    
    140         if((retval != (int)VM_FAILED) || (attr.flags & VM_REG_ANON))
    141                 return retval;
    142 
    143 SYS_MMAP_FILE_ERR:
    144         printk(INFO, "%s: Failed, Droping file count \n",
    145                __FUNCTION__);
    146    
    147         vfs_close( file , &count );
    148 
    149         if(count == 1) process_fd_put( process , attr.fd );
    150 
    151         return (int)VM_FAILED;
    152 */
     178            if( cluster_is_undefined( vseg_cxy ) )
     179            {
     180                printk("\n[ERROR] in %s : illegal cxy for MAP_REMOTE\n", __FUNCTION__ );
     181                this->errno = EINVAL;
     182                return -1;
     183            }
     184        }
     185    }
     186
     187    // get reference process cluster and local pointer
     188    xptr_t      ref_xp  = process->ref_xp;
     189    cxy_t       ref_cxy = GET_CXY( ref_xp );
     190    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
     191
     192    // create the vseg in reference cluster
     193    if( local_cxy == ref_cxy )
     194    {
     195        vseg = vmm_create_vseg( process,
     196                                vseg_type,
     197                                0,               // base address unused for mmap()
     198                                length,
     199                                offset,
     200                                0,               // file_size unused for mmap()
     201                                mapper_xp,
     202                                vseg_cxy );
     203    }
     204    else
     205    {
     206        rpc_vmm_create_vseg_client( ref_cxy,
     207                                    ref_ptr,
     208                                    vseg_type,
     209                                    0,            // base address unused for mmap()
     210                                    length,
     211                                    offset,
     212                                    0,            // file size unused for mmap()
     213                                    mapper_xp,
     214                                    vseg_cxy,
     215                                    &vseg );
     216    }
     217   
     218    if( vseg == NULL )
     219    {
     220        printk("\n[ERROR] in %s : cannot create vseg\n", __FUNCTION__ );
     221        this->errno = ENOMEM;
     222        return -1;
     223    }
     224
     225    // copy vseg base address to user space
     226    hal_copy_to_uspace( &attr->addr , &vseg->min , sizeof(intptr_t) );
     227
     228    tm_end = hal_get_cycles();
     229
     230syscall_dmsg("\n[DBG] %s : core[%x,%d] created vseg %s in cluster %x / cycle %d\n"
     231"      base = %x / length = %x / cost = %d\n",
     232__FUNCTION__, local_cxy , this->core->lid , vseg_type_str(vseg->type) ,
     233vseg->cxy , (uint32_t)tm_start , vseg->min , length , (uint32_t)(tm_end - tm_start) );
     234
     235        return 0;
     236
    153237}  // end sys_mmap()
     238
Note: See TracChangeset for help on using the changeset viewer.