Changeset 407 for trunk/kernel/syscalls/sys_mmap.c
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_mmap.c
r23 r407 24 24 25 25 #include <hal_types.h> 26 #include <hal_uspace.h> 27 #include <shared_syscalls.h> 26 28 #include <errno.h> 27 29 #include <thread.h> 28 30 #include <printk.h> 31 #include <mapper.h> 29 32 #include <vfs.h> 30 33 #include <process.h> 31 34 #include <vmm.h> 32 35 33 ////////////////////////////////// /36 ////////////////////////////////// 34 37 int sys_mmap( mmap_attr_t * attr ) 35 38 { 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; 47 177 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 230 syscall_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) , 233 vseg->cxy , (uint32_t)tm_start , vseg->min , length , (uint32_t)(tm_end - tm_start) ); 234 235 return 0; 236 153 237 } // end sys_mmap() 238
Note: See TracChangeset
for help on using the changeset viewer.