]> Zhao Yanbai Git Server - minix.git/commitdiff
vm: add third-party mmap() mode and PROCCTL
authorBen Gras <ben@minix3.org>
Tue, 5 Jun 2012 22:50:13 +0000 (00:50 +0200)
committerBen Gras <ben@minix3.org>
Thu, 7 Jun 2012 10:43:16 +0000 (12:43 +0200)
these two functions will be used to support all exec() functionality
going into a single library shared by RS and VFS and exec() knowledge
leaving VM.

. third-party mmap: allow certain processes (VFS, RS) to
  do mmap() on behalf of another process
. PROCCTL: used to free and clear a process' address space

12 files changed:
commands/service/parse.c
etc/system.conf
include/minix/com.h
include/minix/vm.h
include/sys/mman.h
lib/libc/sys-minix/mmap.c
lib/libsys/Makefile
lib/libsys/vm_procctl.c [new file with mode: 0644]
servers/vm/exit.c
servers/vm/main.c
servers/vm/mmap.c
servers/vm/proto.h

index 1fe637362449fd09388de632b0e742ee65beea3b..562fa2794dfba575f799eb6a7c3ba412f1f14bf5 100644 (file)
@@ -731,6 +731,7 @@ struct
        { "INFO",               VM_INFO },
        { "RS_UPDATE",          VM_RS_UPDATE },
        { "RS_MEMCTL",          VM_RS_MEMCTL },
+       { "PROCCTL",            VM_PROCCTL },
        { NULL,                 0 },
 };
 
index 6bd3b3b2be725676cf45901c82e521723428ce80..a4e6d61a0bcb23516ba29d3a793a2fb7a1433936 100644 (file)
@@ -11,6 +11,7 @@ service rs
                RS_SET_PRIV     # 37
                RS_UPDATE       # 41
                RS_MEMCTL       # 42
+               PROCCTL
                ;
        io      NONE;           # No I/O range allowed
        irq     NONE;           # No IRQ allowed
@@ -93,7 +94,7 @@ service vfs
                UMAP            # 14
                VIRCOPY         # 15
                ;
-       vm      BASIC;          # Only basic VM calls allowed
+       vm      PROCCTL;
        io      NONE;           # No I/O range allowed
        irq     NONE;           # No IRQ allowed
        sigmgr          rs;     # Signal manager is RS
index 68eff5e879094f6075b0afabba11034ef53dd164..6348550f411605efbf9c2a30bfd1ed33a6e3defa 100644 (file)
 #      define VMM_FLAGS                m5_s2
 #      define VMM_FD                   m5_i1
 #      define VMM_OFFSET               m5_i2
+#      define VMM_FORWHOM              m5_l3
 #      define VMM_RETADDR              m5_l1   /* result */
 #define VM_UMAP                        (VM_RQ_BASE+11)
 #      define VMU_SEG                  m1_i1
 #define VM_REMAP_RO            (VM_RQ_BASE+44)
 /* same args as VM_REMAP */
 
+#define VM_PROCCTL             (VM_RQ_BASE+45)
+#define VMPCTL_PARAM           m1_i1
+#define VMPCTL_WHO             m1_i2
+
+#define VMPPARAM_CLEAR         1       /* values for VMPCTL_PARAM */
+
 /* Total. */
-#define NR_VM_CALLS                            45
+#define NR_VM_CALLS                            46
 #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 626c5406acd6c819eb95c9f6ad1e2745af37d11c..3d46c53648ca3bab8552ec85d7b0299b52c02889 100644 (file)
@@ -70,6 +70,7 @@ int vm_info_stats(struct vm_stats_info *vfi);
 int vm_info_usage(endpoint_t who, struct vm_usage_info *vui);
 int vm_info_region(endpoint_t who, struct vm_region_info *vri, int
        count, vir_bytes *next);
+int vm_procctl(endpoint_t ep, int param);
 
 #endif /* _MINIX_VM_H */
 
index 406db8c9f838766eada9c342e6d56ae42d688346..8ad43fb9bfcdd0eb17ea6c9258372b74156b575f 100644 (file)
@@ -4,6 +4,7 @@
 #include <sys/featuretest.h>
 
 #include <machine/ansi.h>
+#include <minix/type.h>
 
 #ifdef _BSD_SIZE_T_
 typedef        _BSD_SIZE_T_    size_t;
@@ -54,9 +55,10 @@ typedef      __off_t         off_t;          /* file offset */
 #define MAP_ALIGN64K   0x0040          /* physically aligned at 64kB */
 #define MAP_LOWER1M    0x0080          /* physically below 16MB */
 #define        MAP_ALIGNMENT_64KB      MAP_ALIGN64K
-#define        MAP_IPC_SHARED  0x0100  /* share changes */
+#define        MAP_IPC_SHARED  0x0100          /* share changes */
 
 #define MAP_FIXED      0x0200  /* require mapping to happen at hint */
+#define MAP_THIRDPARTY 0x0400          /* perform on behalf of any process */
 
 /*
  * Error indicator returned by mmap(2)
@@ -71,6 +73,7 @@ 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);
 int    minix_munmap(void *, size_t);
 int            minix_munmap_text(void *, size_t);
 void *         vm_remap(int d, int s, void *da, void *sa, size_t si);
index d15e3d1a71b2247a8440dfbe15d19df5ce14a7ba..0fb444345288f31ff26e1be0384932f3939ae75a 100644 (file)
@@ -21,8 +21,8 @@ __weak_alias(minix_munmap_text, _minix_munmap_text)
 #include <string.h>
 #include <errno.h>
 
-void *minix_mmap(void *addr, size_t len, int prot, int flags,
-       int fd, off_t offset)
+void *minix_mmap_for(endpoint_t forwhom,
+       void *addr, size_t len, int prot, int flags, int fd, off_t offset)
 {
        message m;
        int r;
@@ -33,6 +33,11 @@ void *minix_mmap(void *addr, size_t len, int prot, int flags,
        m.VMM_FLAGS = flags;
        m.VMM_FD = fd;
        m.VMM_OFFSET = offset;
+       m.VMM_FORWHOM = forwhom;
+
+       if(forwhom != SELF) {
+               m.VMM_FLAGS |= MAP_THIRDPARTY;
+       }
 
        r = _syscall(VM_PROC_NR, VM_MMAP, &m);
 
@@ -43,6 +48,12 @@ void *minix_mmap(void *addr, size_t len, int prot, int flags,
        return (void *) m.VMM_RETADDR;
 }
 
+void *minix_mmap(void *addr, size_t len, int prot, int flags,
+       int fd, off_t offset)
+{
+       return minix_mmap_for(SELF, addr, len, prot, flags, fd, offset);
+}
+
 int minix_munmap(void *addr, size_t len)
 {
        message m;
index 9201b0bcd956dc762172dc679a30166b63eab5bb..19f1f11fd30258177b11d7803203eec46dbd27da 100644 (file)
@@ -127,6 +127,7 @@ SRCS=  \
        vm_push_sig.c \
        vm_umap.c \
        vm_yield_get_block.c \
+       vm_procctl.c \
        vprintf.c \
 
 .if ${MKCOVERAGE} != "no"
diff --git a/lib/libsys/vm_procctl.c b/lib/libsys/vm_procctl.c
new file mode 100644 (file)
index 0000000..a308168
--- /dev/null
@@ -0,0 +1,22 @@
+
+#include "syslib.h"
+
+#include <minix/vm.h>
+#include <string.h>
+
+/*===========================================================================*
+ *                                vm_exit                                   *
+ *===========================================================================*/
+int vm_procctl(endpoint_t ep, int param)
+{
+    message m;
+    int result;
+
+    memset(&m, 0, sizeof(m));
+
+    m.VMPCTL_WHO = ep;
+    m.VMPCTL_PARAM = param;
+
+    result = _taskcall(VM_PROC_NR, VM_PROCCTL, &m);
+    return(result);
+}
index 04e37ceb28de37994ed5907a1e72a34e1837b3c1..202dc0ba4c1a4a59f0eb6dbc47ab0b6c1c10157f 100644 (file)
@@ -114,3 +114,33 @@ int do_willexit(message *msg)
        return OK;
 }
 
+int do_procctl(message *msg)
+{
+       endpoint_t proc;
+       struct vmproc *vmp;
+
+       if(vm_isokendpt(msg->VMPCTL_WHO, &proc) != OK) {
+               printf("VM: bogus endpoint VM_PROCCTL %d\n",
+                       msg->VMPCTL_WHO);
+               return EINVAL;
+       }
+       vmp = &vmproc[proc];
+
+       switch(msg->VMPCTL_PARAM) {
+               case VMPPARAM_CLEAR:
+                       if(msg->m_source != RS_PROC_NR
+                               && msg->m_source != VFS_PROC_NR)
+                               return EPERM;
+                       free_proc(vmp);
+                       pt_new(&vmp->vm_pt);
+                       vmp->vm_flags |= VMF_HASPT;
+                       pt_bind(&vmp->vm_pt, vmp);
+                       return OK;
+               default:
+                       return EINVAL;
+       }
+
+
+       return OK;
+}
+
index 3f86a8194162e491a23778e5f1ebb7830d14154d..765852acb7a8ade2a51d03ab0c1122049a795c9d 100644 (file)
@@ -357,6 +357,9 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info)
        CALLMAP(VM_RS_UPDATE, do_rs_update);
        CALLMAP(VM_RS_MEMCTL, do_rs_memctl);
 
+       /* Calls from RS/VFS */
+       CALLMAP(VM_PROCCTL, do_procctl);
+
        /* Generic calls. */
        CALLMAP(VM_REMAP, do_remap);
        CALLMAP(VM_REMAP_RO, do_remap);
index b74571613282870bf3ef3369333c0db6dc62e024..8bf843754585263045dbfffbe357103416ff0fb1 100644 (file)
@@ -43,8 +43,18 @@ int do_mmap(message *m)
        vir_bytes addr;
        struct vir_region *vr = NULL;
 
-       if((r=vm_isokendpt(m->m_source, &n)) != OK) {
-               panic("do_mmap: message from strange source: %d", m->m_source);
+       if(m->VMM_FLAGS & MAP_THIRDPARTY) {
+               /* exec()ers, i.e. RS & VFS, can mmap() on behalf of anyone. */
+               if(m->m_source != VFS_PROC_NR && m->m_source != RS_PROC_NR)
+                       return EPERM;
+               if((r=vm_isokendpt(m->VMM_FORWHOM, &n)) != OK)
+                       return ESRCH;
+       } else {
+               /* regular mmap, i.e. for caller */
+               if((r=vm_isokendpt(m->m_source, &n)) != OK) {
+                       panic("do_mmap: message from strange source: %d",
+                               m->m_source);
+               }
        }
 
        vmp = &vmproc[n];
index 3e1f9d4451cfa441edbe0f034581a104ed84dd68..3168ce9af2678a2b15607b2cff9e38ea61c880ba 100644 (file)
@@ -52,6 +52,7 @@ int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp);
 void clear_proc(struct vmproc *vmp);
 int do_exit(message *msg);
 int do_willexit(message *msg);
+int do_procctl(message *msg);
 void free_proc(struct vmproc *vmp);
 
 /* fork.c */