@@ -463,6 +463,75 @@ static int do_write(int fd, const void *buffer, int count)
463463 return ret ;
464464}
465465
466+ /* Low Level mmap */
467+ static int do_mmap (int fd , addr_t virt_addr , uint32_t page_count , off_t offset )
468+ {
469+ int gfd ;
470+ struct file_operations * fops ;
471+
472+ /* Get the fops associated to the file descriptor. */
473+ gfd = vfs_get_gfd (fd );
474+ if (-1 == gfd ) {
475+ printk ("%s: could not get global fd.\n" , __func__ );
476+ return - EBADF ;
477+ }
478+
479+ mutex_lock (& vfs_lock );
480+ fops = vfs_get_fops (gfd );
481+ if (!fops ) {
482+ printk ("%s: could not get device fops.\n" , __func__ );
483+ mutex_unlock (& vfs_lock );
484+ return - EBADF ;
485+ }
486+
487+ mutex_unlock (& vfs_lock );
488+
489+ if (!fops -> mmap ) {
490+ printk ("%s: device doesn't support mmap.\n" , __func__ );
491+ return - EACCES ;
492+ }
493+
494+ /* Call the mmap fops that will do the actual mapping. */
495+ return (long ) fops -> mmap (fd , virt_addr , page_count , offset );
496+ }
497+
498+ /* Low Level mmap - Anonymous case */
499+ static int do_mmap_anon (int fd , addr_t virt_addr , uint32_t page_count , off_t offset )
500+ {
501+ uint32_t page ;
502+ pcb_t * pcb ;
503+ int i ;
504+
505+ if (offset != 0 ) {
506+ printk ("%s: Offset should be 0 with MAP_ANONYMOUS flag\n" , __func__ );
507+ return - EINVAL ;
508+ }
509+
510+ pcb = current ()-> pcb ;
511+
512+ /* Start is smaller or NULL than initial virt_addr pointer */
513+ if (virt_addr < pcb -> next_anon_start )
514+ virt_addr = pcb -> next_anon_start ;
515+
516+ for (i = 0 ; i < page_count ; i ++ ) {
517+ page = get_free_page ();
518+ BUG_ON (!page );
519+
520+ create_mapping (pcb -> pgtable , virt_addr + (i * PAGE_SIZE ), page , PAGE_SIZE , false);
521+ add_page_to_proc (pcb , phys_to_page (page ));
522+ }
523+
524+ memset ((void * ) virt_addr , 0 , page_count * PAGE_SIZE );
525+
526+ /* WARNIMG - This is a simple/basic way to set the start virtual address:
527+ It only increment the start address after each mmap call, no algorithm
528+ to search for available spaces.
529+ */
530+ pcb -> next_anon_start = virt_addr + (page_count * PAGE_SIZE );
531+
532+ return virt_addr ;
533+ }
534+
466535SYSCALL_DEFINE3 (read , int , fd , void * , buffer , int , count )
467536{
468537 return do_read (fd , buffer , count );
@@ -738,43 +807,20 @@ SYSCALL_DEFINE2(stat, const char *, path, struct stat *, st)
738807/**
739808 * An mmap() implementation in VFS.
740809 */
741- SYSCALL_DEFINE5 (mmap , addr_t , start , size_t , length , int , prot , int , fd , off_t , offset )
810+ SYSCALL_DEFINE6 (mmap , addr_t , start , size_t , length , int , prot , int , flags , int , fd , off_t , offset )
742811{
743- int gfd ;
744812 uint32_t page_count ;
745- struct file_operations * fops ;
746-
747- /* Get the fops associated to the file descriptor. */
748-
749- gfd = vfs_get_gfd (fd );
750- if (-1 == gfd ) {
751- printk ("%s: could not get global fd.\n" , __func__ );
752- return - EBADF ;
753- }
754-
755- mutex_lock (& vfs_lock );
756- fops = vfs_get_fops (gfd );
757- if (!fops ) {
758- printk ("%s: could not get device fops.\n" , __func__ );
759- mutex_unlock (& vfs_lock );
760- return - EBADF ;
761- }
762-
763- mutex_unlock (& vfs_lock );
764813
765814 /* Page count to allocate to the current process to be able to map the desired region. */
766815 page_count = length / PAGE_SIZE ;
767816 if (length % PAGE_SIZE != 0 ) {
768817 page_count ++ ;
769818 }
770819
771- if (!fops -> mmap ) {
772- printk ("%s: device doesn't support mmap.\n" , __func__ );
773- return - EACCES ;
774- }
775-
776- /* Call the mmap fops that will do the actual mapping. */
777- return (long ) fops -> mmap (fd , start , page_count , offset );
820+ if (flags & MAP_ANONYMOUS )
821+ return do_mmap_anon (fd , start , page_count , offset );
822+ else
823+ return do_mmap (fd , start , page_count , offset );
778824}
779825
780826SYSCALL_DEFINE3 (ioctl , int , fd , unsigned long , cmd , unsigned long , args )
0 commit comments