]> Zhao Yanbai Git Server - minix.git/commitdiff
vm_remap_ro
authorBen Gras <ben@minix3.org>
Mon, 28 Nov 2011 18:05:50 +0000 (19:05 +0100)
committerTomas Hruby <tom@minix3.org>
Fri, 13 Jan 2012 11:30:01 +0000 (11:30 +0000)
- allows shared memory to be mapped in readonly

- ben@minix3.org & tom@minix3.org

commands/service/parse.c
common/include/minix/com.h
include/sys/mman.h
lib/libc/posix/_mmap.c
lib/nbsd_libc/sys-minix/mmap.c
servers/ipc/ipc.conf
servers/vm/main.c
servers/vm/mmap.c
servers/vm/pagefaults.c
servers/vm/proto.h
servers/vm/region.c

index 20096e0e02174331ca0bc90a527f26a31026d26b..ed675d4f00ff05c899094166103e9d420ece1242 100644 (file)
@@ -716,6 +716,7 @@ struct
        { "DELDMA",             VM_DELDMA },
        { "GETDMA",             VM_GETDMA },
        { "REMAP",              VM_REMAP },
+       { "REMAP_RO",           VM_REMAP_RO },
        { "SHM_UNMAP",          VM_SHM_UNMAP },
        { "GETPHYS",            VM_GETPHYS },
        { "GETREF",             VM_GETREF },
index 6786376733f91fda4bf75e7c38b0fed130bc52ae..7047ff6d0ad940c117681eaba89c00ff5662f40a 100644 (file)
 #      define VMRE_SA                  m1_p2
 #      define VMRE_RETA                m1_p3
 #      define VMRE_SIZE                m1_i3
+#      define VMRE_FLAGS               m1_i3
 
 #define VM_SHM_UNMAP           (VM_RQ_BASE+34)
 #      define VMUN_ENDPT               m2_i1
 #define VM_WATCH_EXIT          (VM_RQ_BASE+43)
 #      define VM_WE_EP         m1_i1
 
+#define VM_REMAP_RO            (VM_RQ_BASE+44)
+/* same args as VM_REMAP */
+
 /* Total. */
-#define NR_VM_CALLS                            44
+#define NR_VM_CALLS                            45
 #define VM_CALL_MASK_SIZE                      BITMAP_CHUNKS(NR_VM_CALLS)
 
 /* not handled as a normal VM call, thus at the end of the reserved rage */
index 7317ea606b5a438bde43632903f889e8fcccfc85..b08c912bc8a30c105b66c0937f3ab109c2e1ea28 100644 (file)
@@ -30,6 +30,8 @@ _PROTOTYPE( int minix_munmap, (void *, size_t));
 _PROTOTYPE( int minix_munmap_text, (void *, size_t));
 _PROTOTYPE( void *vm_remap, (endpoint_t d, endpoint_t s, void *da,
                                void *sa, size_t si));
+_PROTOTYPE( void *vm_remap_ro, (endpoint_t d, endpoint_t s, void *da,
+                               void *sa, size_t si));
 _PROTOTYPE( int vm_unmap, (endpoint_t endpt, void *addr));
 _PROTOTYPE( unsigned long vm_getphys, (endpoint_t endpt, void *addr));
 _PROTOTYPE( u8_t vm_getrefcount, (endpoint_t endpt, void *addr));
index 8497fddc4e6784c1a598b10679a3df0cde38333a..42605beb66a09eb252445358a0b140c6770d1e76 100644 (file)
@@ -76,6 +76,28 @@ PUBLIC void *vm_remap(endpoint_t d,
        return (void *) m.VMRE_RETA;
 }
 
+PUBLIC void *vm_remap_ro(endpoint_t d,
+                       endpoint_t s,
+                       void *da,
+                       void *sa,
+                       size_t size)
+{
+       message m;
+       int r;
+
+       m.VMRE_D = d;
+       m.VMRE_S = s;
+       m.VMRE_DA = (char *) da;
+       m.VMRE_SA = (char *) sa;
+       m.VMRE_SIZE = size;
+
+       r = _syscall(VM_PROC_NR, VM_REMAP_RO, &m);
+       if (r != OK)
+               return MAP_FAILED;
+       return (void *) m.VMRE_RETA;
+}
+
+
 PUBLIC int vm_unmap(endpoint_t endpt, void *addr)
 {
        message m;
index 1a0ea36d0f06c8ca3821cb64d4fe7bc86f41aac9..d49d495fda4a8c0b2d28b0c68fbfef8263ddc099 100644 (file)
@@ -85,6 +85,27 @@ PUBLIC void *vm_remap(endpoint_t d,
        return (void *) m.VMRE_RETA;
 }
 
+PUBLIC void *vm_remap_ro(endpoint_t d,
+                       endpoint_t s,
+                       void *da,
+                       void *sa,
+                       size_t size)
+{
+       message m;
+       int r;
+
+       m.VMRE_D = d;
+       m.VMRE_S = s;
+       m.VMRE_DA = (char *) da;
+       m.VMRE_SA = (char *) sa;
+       m.VMRE_SIZE = size;
+
+       r = _syscall(VM_PROC_NR, VM_REMAP_RO, &m);
+       if (r != OK)
+               return MAP_FAILED;
+       return (void *) m.VMRE_RETA;
+}
+
 PUBLIC int vm_unmap(endpoint_t endpt, void *addr)
 {
        message m;
index a4cc015fc2106fb80698800d5ffbf0840925d854..e2300e6bbf76db23b8e4a1405b511987ddef4d71 100644 (file)
@@ -10,6 +10,7 @@ service ipc
                ;
        vm
                REMAP
+               REMAP_RO
                SHM_UNMAP
                GETPHYS
                GETREF
index 43a07b78d1a23e17c56f02fbea412205d4054501..9a32356faf0eefb97b06564b715675e30fc65227 100644 (file)
@@ -361,6 +361,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
 
        /* Generic calls. */
        CALLMAP(VM_REMAP, do_remap);
+       CALLMAP(VM_REMAP_RO, do_remap);
        CALLMAP(VM_GETPHYS, do_get_phys);
        CALLMAP(VM_SHM_UNMAP, do_shared_unmap);
        CALLMAP(VM_GETREF, do_get_refcount);
index 2659b6e45f38e597d28d8bc4f2c5e144f8731938..8e1c3abc4d9b9f1cd4c856b058d7ee5d1190db3b 100644 (file)
@@ -231,6 +231,13 @@ PUBLIC int do_remap(message *m)
        struct vir_region *region;
        struct vmproc *dvmp, *svmp;
        int r;
+       int readonly;
+
+       if(m->m_type == VM_REMAP)
+               readonly = 0;
+       else if(m->m_type == VM_REMAP_RO)
+               readonly = 1;
+       else panic("do_remap: can't be");
 
        da = (vir_bytes) m->VMRE_DA;
        sa = (vir_bytes) m->VMRE_SA;
@@ -275,7 +282,7 @@ PUBLIC int do_remap(message *m)
                return EFAULT;
        }
 
-       if ((r = map_remap(dvmp, da, size, region, &startv)) != OK)
+       if ((r = map_remap(dvmp, da, size, region, &startv, readonly)) != OK)
                return r;
 
        m->VMRE_RETA = (char *) arch_map2vir(dvmp, startv);
index fae6373a94c5e78bf3299000494923550c03c897..6b6575c63e5678e4604e5599c04fad7f9912f318 100644 (file)
@@ -86,11 +86,6 @@ PUBLIC void do_pagefaults(message *m)
         */
        assert(!(region->flags & VR_NOPF));
 
-       /* We do not allow shared memory to cause pagefaults.
-        * These pages have to be pre-allocated.
-        */
-       assert(!(region->flags & VR_SHARED));
-
        /* If process was writing, see if it's writable. */
        if(!(region->flags & VR_WRITABLE) && wr) {
                printf("VM: pagefault: SIGSEGV %d ro map 0x%lx %s\n",
index 506e59d78e2e43f033b1e46e4808d4ca9991263b..8b861d3ad5044414d0df3c1759aae3789e213f60 100644 (file)
@@ -169,7 +169,7 @@ _PROTOTYPE(struct vir_region * map_region_lookup_tag, (struct vmproc *vmp, u32_t
 _PROTOTYPE(void map_region_set_tag, (struct vir_region *vr, u32_t tag));
 _PROTOTYPE(u32_t map_region_get_tag, (struct vir_region *vr));
 _PROTOTYPE(int map_remap, (struct vmproc *dvmp, vir_bytes da, size_t size,
-       struct vir_region *region, vir_bytes *r));
+       struct vir_region *region, vir_bytes *r, int ro));
 _PROTOTYPE(int map_get_phys, (struct vmproc *vmp, vir_bytes addr, phys_bytes *r));
 _PROTOTYPE(int map_get_ref, (struct vmproc *vmp, vir_bytes addr, u8_t *cnt));
 
index 2d63e1954117365cc3f85ea6b7634d5b3a50db68..ad375e54b93f31d597c9d4e4bd4c87d28f13011e 100644 (file)
@@ -36,8 +36,9 @@ PRIVATE yielded_t *lru_youngest = NULL, *lru_oldest = NULL;
 
 /* Should a physblock be mapped writable? */
 #define WRITABLE(r, pb) \
-       (((r)->flags & (VR_DIRECT | VR_SHARED)) ||      \
-        (((r)->flags & VR_WRITABLE) && (pb)->refcount == 1))
+       (((r)->flags & VR_WRITABLE) &&                  \
+               (((r)->flags & (VR_DIRECT | VR_SHARED)) ||      \
+                (pb)->refcount == 1))
 
 FORWARD _PROTOTYPE(int map_new_physblock, (struct vmproc *vmp,
        struct vir_region *region, vir_bytes offset, vir_bytes length,
@@ -1426,6 +1427,7 @@ PRIVATE struct vir_region *map_copy_region(struct vmproc *vmp, struct vir_region
                newvr->lower = newvr->higher = NULL;
                newvr->phys = phavl;
        );
+
        physr_init(newvr->phys);
 
        physr_start_iter_least(vr->phys, &iter);
@@ -1806,7 +1808,7 @@ PUBLIC int map_unmap_region(struct vmproc *vmp, struct vir_region *r,
  *                             map_remap                                 *
  *========================================================================*/
 PUBLIC int map_remap(struct vmproc *dvmp, vir_bytes da, size_t size,
-               struct vir_region *region, vir_bytes *r)
+               struct vir_region *region, vir_bytes *r, int readonly)
 {
        struct vir_region *vr;
        struct phys_region *ph;
@@ -1843,7 +1845,11 @@ PUBLIC int map_remap(struct vmproc *dvmp, vir_bytes da, size_t size,
        vr->length = size;
        vr->flags = region->flags;
        vr->tag = VRT_NONE;
-       vr->parent = dvmp;);
+       vr->parent = dvmp;
+         if(readonly) {
+               vr->flags &= ~VR_WRITABLE;
+         }
+       );
        assert(vr->flags & VR_SHARED);
 
        region_insert(&dvmp->vm_regions_avl, vr);