]> Zhao Yanbai Git Server - minix.git/commitdiff
VM: 64-bit mmap() 15/415/6
authorBen Gras <ben@minix3.org>
Wed, 20 Mar 2013 18:45:10 +0000 (18:45 +0000)
committerBen Gras <ben@minix3.org>
Wed, 24 Apr 2013 10:18:15 +0000 (10:18 +0000)
Some (backwards-compatible) changes in mmap() call message fields
that allow for a 64-bit offset. minix_mmap() takes an off_t and
minix_mmap64() takes a u64_t. Some mmap() work in VM goes into a
separate function, using the new fields, so that that can be re-used
when files are to be mapped (future commit).

Change-Id: Ifb77a90b593dd3c33cf81b396068e4da1ec5fb1c

include/minix/com.h
lib/libc/sys-minix/mmap.c
servers/vm/mmap.c
sys/sys/mman.h

index c43c412ddccca2f3791ae311f785869a18f8cd69..1daa0409a7ec81a9d59bfdd1e7c4d322745d62c3 100644 (file)
 #      define VMM_PROT                 m5_s1
 #      define VMM_FLAGS                m5_s2
 #      define VMM_FD                   m5_i1
-#      define VMM_OFFSET               m5_i2
+#      define VMM_OFFSET_LO            m5_i2
 #      define VMM_FORWHOM              m5_l3
+#      define VMM_OFFSET_HI            m5_l3
 #      define VMM_RETADDR              m5_l1   /* result */
 #define VM_UMAP                        (VM_RQ_BASE+11)
 #      define VMU_SEG                  m1_i1
index 19e4d8170bc9acad5c515cd45566f50a83755a68..4a3de773e8410307b835ee552c59f0bf70b258cc 100644 (file)
@@ -2,6 +2,8 @@
 #include <sys/cdefs.h>
 #include "namespace.h"
 #include <lib.h>
+#include <minix/u64.h>
+#include <minix/vm.h>
 
 /* INCLUDES HERE */
 
@@ -21,7 +23,7 @@ __weak_alias(minix_munmap, _minix_munmap)
 #include <errno.h>
 
 void *minix_mmap_for(endpoint_t forwhom,
-       void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+       void *addr, size_t len, int prot, int flags, int fd, u64_t offset)
 {
        message m;
        int r;
@@ -31,11 +33,13 @@ void *minix_mmap_for(endpoint_t forwhom,
        m.VMM_PROT = prot;
        m.VMM_FLAGS = flags;
        m.VMM_FD = fd;
-       m.VMM_OFFSET = offset;
-       m.VMM_FORWHOM = forwhom;
+       m.VMM_OFFSET_LO = ex64lo(offset);
 
        if(forwhom != SELF) {
                m.VMM_FLAGS |= MAP_THIRDPARTY;
+               m.VMM_FORWHOM = forwhom;
+       } else {
+               m.VMM_OFFSET_HI = ex64hi(offset);
        }
 
        r = _syscall(VM_PROC_NR, VM_MMAP, &m);
index 8a9bf22e6ce6c5da0fb5eabdbf3092f1f400b8a7..1cdc677a0a844fe8421458677f9bda83dde3147e 100644 (file)
 #include "util.h"
 #include "region.h"
 
+
+static struct vir_region *mmap_region(struct vmproc *vmp, vir_bytes addr,
+       u32_t vmm_flags, size_t len, u32_t vrflags,
+       mem_type_t *mt, int execpriv)
+{
+       u32_t mfflags = 0;
+       struct vir_region *vr = NULL;
+
+       if(vmm_flags & MAP_LOWER16M) vrflags |= VR_LOWER16MB;
+       if(vmm_flags & MAP_LOWER1M)  vrflags |= VR_LOWER1MB;
+       if(vmm_flags & MAP_ALIGN64K) vrflags |= VR_PHYS64K;
+       if(vmm_flags & MAP_PREALLOC) mfflags |= MF_PREALLOC;
+       if(vmm_flags & MAP_UNINITIALIZED) {
+               if(!execpriv) return NULL;
+               vrflags |= VR_UNINITIALIZED;
+       }
+
+       if(len <= 0) {
+               return NULL;
+       }
+
+       if(len % VM_PAGE_SIZE)
+               len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
+
+#if 0
+       /* MAP_FIXED is restored in a later commit */
+       if (addr && (vmm_flags & MAP_FIXED)) {
+               int r = map_unmap_range(vmp, addr, len);
+               if(r != OK) {
+                       printf("mmap_region: map_unmap_range failed (%d)\n", r);
+                       return NULL;
+               }
+       }
+#endif
+
+       if (addr || (vmm_flags & MAP_FIXED)) {
+               /* An address is given, first try at that address. */
+               vr = map_page_region(vmp, addr, 0, len,
+                       vrflags, mfflags, mt);
+               if(!vr && (vmm_flags & MAP_FIXED))
+                       return NULL;
+       }
+
+       if (!vr) {
+               /* No address given or address already in use. */
+               vr = map_page_region(vmp, VM_PAGE_SIZE, VM_DATATOP, len,
+                       vrflags, mfflags, mt);
+       }
+
+       return vr;
+}
+
 /*===========================================================================*
  *                             do_mmap                                      *
  *===========================================================================*/
@@ -39,10 +91,10 @@ int do_mmap(message *m)
 {
        int r, n;
        struct vmproc *vmp;
-       int mfflags = 0;
-       vir_bytes addr;
+       vir_bytes addr = m->VMM_ADDR;
        struct vir_region *vr = NULL;
        int execpriv = 0;
+       size_t len = (vir_bytes) m->VMM_LEN;
 
        /* RS and VFS can do slightly more special mmap() things */
        if(m->m_source == VFS_PROC_NR || m->m_source == RS_PROC_NR)
@@ -63,11 +115,11 @@ int do_mmap(message *m)
        vmp = &vmproc[n];
 
        if(m->VMM_FD == -1 || (m->VMM_FLAGS & MAP_ANON)) {
-               mem_type_t *mt;
-               u32_t vrflags = VR_ANON | VR_WRITABLE;
-               size_t len = (vir_bytes) m->VMM_LEN;
+               /* actual memory in some form */
+               mem_type_t *mt = NULL;
 
                if(m->VMM_FD != -1 || len <= 0) {
+                       printf("VM: mmap: fd %d, len 0x%x\n", m->VMM_FD, len);
                        return EINVAL;
                }
 
@@ -76,48 +128,21 @@ int do_mmap(message *m)
                        return EINVAL;
                }
 
-               if(m->VMM_FLAGS & MAP_PREALLOC) mfflags |= MF_PREALLOC;
-               if(m->VMM_FLAGS & MAP_LOWER16M) vrflags |= VR_LOWER16MB;
-               if(m->VMM_FLAGS & MAP_LOWER1M)  vrflags |= VR_LOWER1MB;
-               if(m->VMM_FLAGS & MAP_ALIGN64K) vrflags |= VR_PHYS64K;
-               if(m->VMM_FLAGS & MAP_UNINITIALIZED) {
-                       if(!execpriv) return EPERM;
-                       vrflags |= VR_UNINITIALIZED;
-               }
                if(m->VMM_FLAGS & MAP_CONTIG) {
-                       vrflags |= VR_CONTIG;
                        mt = &mem_type_anon_contig;
                } else  mt = &mem_type_anon;
 
-               if(len % VM_PAGE_SIZE)
-                       len += VM_PAGE_SIZE - (len % VM_PAGE_SIZE);
-
-               vr = NULL;
-               if (m->VMM_ADDR || (m->VMM_FLAGS & MAP_FIXED)) {
-                       /* An address is given, first try at that address. */
-                       addr = m->VMM_ADDR;
-                       vr = map_page_region(vmp, addr, 0, len,
-                               vrflags, mfflags, mt);
-                       if(!vr && (m->VMM_FLAGS & MAP_FIXED))
-                               return ENOMEM;
-               }
-               if (!vr) {
-                       /* No address given or address already in use. */
-                       vr = map_page_region(vmp, 0, VM_DATATOP, len,
-                               vrflags, mfflags, mt);
-               }
-               if (!vr) {
+               if(!(vr = mmap_region(vmp, addr, m->VMM_FLAGS, len,
+                       VR_WRITABLE | VR_ANON, mt, execpriv))) {
                        return ENOMEM;
                }
        } else {
-               return ENOSYS;
+               return ENXIO;
        }
 
        /* Return mapping, as seen from process. */
-       assert(vr);
        m->VMM_RETADDR = vr->vaddr;
 
-
        return OK;
 }
 
index c4265f563f3caa817afd731fcc7607c4dd1ef3d3..2c37e14c40b883308b8ba169233473a68f27509b 100644 (file)
@@ -106,7 +106,8 @@ void *      mmap(void *, size_t, int, int, int, off_t);
 int    munmap(void *, size_t);
 #else
 void * minix_mmap(void *, size_t, int, int, int, off_t);
-void * minix_mmap_for(endpoint_t, void *, size_t, int, int, int, off_t);
+void * minix_mmap64(void *, size_t, int, int, int, u64_t);
+void * minix_mmap_for(endpoint_t, void *, size_t, int, int, int, u64_t);
 int    minix_munmap(void *, size_t);
 void *         vm_remap(endpoint_t d, endpoint_t s, void *da, void *sa, size_t si);
 void *         vm_remap_ro(endpoint_t d, endpoint_t s, void *da, void *sa, size_t si);