]> Zhao Yanbai Git Server - minix.git/commitdiff
further libexec generalization
authorBen Gras <ben@minix3.org>
Wed, 6 Jun 2012 17:05:28 +0000 (19:05 +0200)
committerBen Gras <ben@minix3.org>
Thu, 7 Jun 2012 13:15:02 +0000 (15:15 +0200)
. new mode for sys_memset: include process so memset can be
  done in physical or virtual address space.
. add a mode to mmap() that lets a process allocate uninitialized
  memory.
. this allows an exec()er (RS, VFS, etc.) to request uninitialized
  memory from VM and selectively clear the ranges that don't come
  from a file, leaving no uninitialized memory left for the process
  to see.
. use callbacks for clearing the process, clearing memory in the
  process, and copying into the process; so that the libexec code
  can be used from rs, vfs, and in the future, kernel (to load vm)
  and vm (to load boot-time processes)

21 files changed:
commands/service/parse.c
etc/system.conf
include/minix/com.h
include/minix/syslib.h
include/sys/mman.h
kernel/arch/i386/exception.c
kernel/arch/i386/include/arch_proto.h
kernel/arch/i386/klib.S
kernel/arch/i386/memory.c
kernel/proto.h
kernel/system/do_memset.c
lib/libexec/exec_elf.c
lib/libexec/exec_general.c
lib/libexec/libexec.h
lib/libsys/sys_memset.c
servers/rs/exec.c
servers/vfs/exec.c
servers/vm/alloc.c
servers/vm/mmap.c
servers/vm/region.c
servers/vm/region.h

index 562fa2794dfba575f799eb6a7c3ba412f1f14bf5..7874f1c397682eb197a7ba4276731049b7a73923 100644 (file)
@@ -819,6 +819,7 @@ struct
        { "READBIOS",           SYS_READBIOS },
        { "STIME",              SYS_STIME },
        { "VMCTL",              SYS_VMCTL },
+       { "MEMSET",             SYS_MEMSET },
        { NULL,         0 }
 };
 
index a4e6d61a0bcb23516ba29d3a793a2fb7a1433936..22b3891978a142d84eb9849a833d598885aa490a 100644 (file)
@@ -93,6 +93,7 @@ service vfs
                KILL            # 06
                UMAP            # 14
                VIRCOPY         # 15
+               MEMSET
                ;
        vm      PROCCTL;
        io      NONE;           # No I/O range allowed
index 6348550f411605efbf9c2a30bfd1ed33a6e3defa..3170accb8046998356203a3d78d3e593a50b71ba 100644 (file)
 #define MEM_PTR                m2_p1   /* base */
 #define MEM_COUNT      m2_l1   /* count */
 #define MEM_PATTERN    m2_l2   /* pattern to write */
+#define MEM_PROCESS    m2_i1   /* NONE (phys) or process id (vir) */
 
 /* Field names for SYS_DEVIO, SYS_VDEVIO, SYS_SDEVIO. */
 #define DIO_REQUEST    m2_i3   /* device in or output */
index e1d82e5e2883a8560f59019f54f6b144e0ed6c85..b427cd8cc80c36c1b2cb20437a11f445b95bd305 100644 (file)
@@ -153,8 +153,8 @@ int sys_safecopyto(endpoint_t dest, cp_grant_id_t grant, vir_bytes
        grant_offset, vir_bytes my_address, size_t bytes, int my_seg);
 int sys_vsafecopy(struct vscp_vec *copyvec, int elements);
 
-int sys_memset(unsigned long pattern, phys_bytes base, phys_bytes
-       bytes);
+int sys_memset(endpoint_t who, unsigned long pattern,
+       phys_bytes base, phys_bytes bytes);
 
 /* Grant-based map functions. */
 int sys_safemap(endpoint_t grantor, cp_grant_id_t grant, vir_bytes
index 8ad43fb9bfcdd0eb17ea6c9258372b74156b575f..7ef464bc056b75db24aea030ee8a71230b968fdd 100644 (file)
@@ -59,6 +59,7 @@ typedef       __off_t         off_t;          /* file offset */
 
 #define MAP_FIXED      0x0200  /* require mapping to happen at hint */
 #define MAP_THIRDPARTY 0x0400          /* perform on behalf of any process */
+#define MAP_UNINITIALIZED 0x0800       /* do not clear memory */
 
 /*
  * Error indicator returned by mmap(2)
index e8dd6ac6a402a9805bd51cf17aff45650b794dd8..e0a8fae26982cc62db8c86eab7ebe512564a1af9 100644 (file)
@@ -52,7 +52,7 @@ static void pagefault( struct proc *pr,
                        struct exception_frame * frame,
                        int is_nested)
 {
-       int in_physcopy = 0;
+       int in_physcopy = 0, in_memset = 0;
 
        reg_t pagefaultcr2;
        message m_pagefault;
@@ -68,13 +68,21 @@ static void pagefault( struct proc *pr,
        in_physcopy = (frame->eip > (vir_bytes) phys_copy) &&
           (frame->eip < (vir_bytes) phys_copy_fault);
 
+       in_memset = (frame->eip > (vir_bytes) phys_memset) &&
+          (frame->eip < (vir_bytes) memset_fault);
+
        if((is_nested || iskernelp(pr)) &&
-               catch_pagefaults && in_physcopy) {
+               catch_pagefaults && (in_physcopy || in_memset)) {
 #if 0
                printf("pf caught! addr 0x%lx\n", pagefaultcr2);
 #endif
                if (is_nested) {
-                       frame->eip = (reg_t) phys_copy_fault_in_kernel;
+                       if(in_physcopy) {
+                               assert(!in_memset);
+                               frame->eip = (reg_t) phys_copy_fault_in_kernel;
+                       } else {
+                               frame->eip = (reg_t) memset_fault_in_kernel;
+                       }
                }
                else {
                        pr->p_reg.pc = (reg_t) phys_copy_fault;
index a19d98ec77d17ee015d2004e96440c784bd91b87..2f03715fe209411d23124d26ce878292c9064abd 100644 (file)
@@ -90,7 +90,7 @@ void phys_outsw(u16_t port, phys_bytes buf, size_t count);
 u32_t read_cr3(void);
 void reload_cr3(void);
 void i386_invlpg(phys_bytes linaddr);
-void phys_memset(phys_bytes ph, u32_t c, phys_bytes bytes);
+vir_bytes phys_memset(phys_bytes ph, u32_t c, phys_bytes bytes);
 void reload_ds(void);
 void ia32_msr_read(u32_t reg, u32_t * hi, u32_t * lo);
 void ia32_msr_write(u32_t reg, u32_t hi, u32_t lo);
index 20ea883065e8eb9673bfc23e16a9c0052387c157..4b2eebf40aa657ff484a3e20215efc5661522cd7 100644 (file)
@@ -391,13 +391,24 @@ remain_fill:
        inc     %ebp
        dec     %eax
        jmp     remain_fill
+
 fill_done:
+LABEL(memset_fault)            /* kernel can send us here */
+       mov     $0, %eax                /* 0 means: no fault */
        pop     %ds
        pop     %ebx
        pop     %esi
        pop     %ebp
        ret
 
+LABEL(memset_fault_in_kernel)          /* kernel can send us here */
+       pop     %ds
+       pop     %ebx
+       pop     %esi
+       pop     %ebp
+       mov     %cr2, %eax
+       ret
+
 
 /*===========================================================================*/
 /*                             mem_rdw                                      */
index be359af3174787450fe6f677f84e0c48f67e9f46..b3dbe8c22de96f48cc02eed20fef86b99c9a486b 100644 (file)
@@ -662,16 +662,27 @@ static void vm_print(u32_t *root)
 }
 #endif
 
-/*===========================================================================*
- *                             lin_memset                                   *
- *===========================================================================*/
-int vm_phys_memset(phys_bytes ph, const u8_t c, phys_bytes bytes)
+int vm_memset(endpoint_t who, phys_bytes ph, const u8_t c, phys_bytes bytes)
 {
        u32_t p;
-
+       int r = OK;
+       struct proc *whoptr = NULL;
+       
+       /* NONE for physical, otherwise virtual */
+       if(who != NONE) {
+               int n;
+               vir_bytes lin;
+               assert(vm_running);
+               if(!isokendpt(who, &n)) return ESRCH;
+               whoptr = proc_addr(n);
+               if(!(lin = umap_local(whoptr, D, ph, bytes))) return EFAULT;
+               ph = lin;
+       } 
+       
        p = c | (c << 8) | (c << 16) | (c << 24);
 
        if(!vm_running) {
+               if(who != NONE) panic("can't vm_memset without vm running");
                phys_memset(ph, p, bytes);
                return OK;
        }
@@ -680,24 +691,34 @@ int vm_phys_memset(phys_bytes ph, const u8_t c, phys_bytes bytes)
 
        assert(get_cpulocal_var(ptproc)->p_seg.p_cr3_v);
 
-       /* With VM, we have to map in the physical memory. 
+       assert(!catch_pagefaults);
+       catch_pagefaults=1;
+
+       /* With VM, we have to map in the memory (virtual or physical). 
         * We can do this 4MB at a time.
         */
        while(bytes > 0) {
                int changed = 0;
-               phys_bytes chunk = bytes, ptr;
-               ptr = createpde(NULL, ph, &chunk, 0, &changed);
+               phys_bytes chunk = bytes, ptr, pfa;
+               ptr = createpde(whoptr, ph, &chunk, 0, &changed);
                if(changed)
                        reload_cr3(); 
 
                /* We can memset as many bytes as we have remaining,
                 * or as many as remain in the 4MB chunk we mapped in.
                 */
-               phys_memset(ptr, p, chunk);
+               if((pfa=phys_memset(ptr, p, chunk))) {
+                       printf("kernel memset pagefault\n");
+                       r = EFAULT;
+                       break;
+               }
                bytes -= chunk;
                ph += chunk;
        }
 
+       assert(catch_pagefaults);
+       catch_pagefaults=0;
+
        assert(get_cpulocal_var(ptproc)->p_seg.p_cr3_v);
 
        return OK;
index 3eaf28e7a3905ae188c21404a9784c4c416399b7..b647f995d627006200836a7385c299cd33947b07 100644 (file)
@@ -157,6 +157,8 @@ phys_bytes phys_copy(phys_bytes source, phys_bytes dest, phys_bytes
        count);
 void phys_copy_fault(void);
 void phys_copy_fault_in_kernel(void);
+void memset_fault(void);
+void memset_fault_in_kernel(void);
 #define virtual_copy(src, dst, bytes) \
                                virtual_copy_f(NULL, src, dst, bytes, 0)
 #define virtual_copy_vmcheck(caller, src, dst, bytes) \
@@ -174,7 +176,8 @@ phys_bytes umap_local(register struct proc *rp, int seg, vir_bytes
 phys_bytes umap_virtual(struct proc* rp, int seg, vir_bytes vir_addr,
        vir_bytes bytes);
 phys_bytes seg2phys(u16_t);
-int vm_phys_memset(phys_bytes source, u8_t pattern, phys_bytes count);
+int vm_memset(endpoint_t who,
+       phys_bytes source, u8_t pattern, phys_bytes count);
 int intr_init(int, int);
 void halt_cpu(void);
 void arch_init(void);
index fdce9a2f66810287c867ab89d04052236727145a..f7db063d83a35430f5dc097c1cbdf45fad343d72 100644 (file)
@@ -18,7 +18,8 @@ int do_memset(struct proc * caller, message * m_ptr)
 {
 /* Handle sys_memset(). This writes a pattern into the specified memory. */
   unsigned char c = m_ptr->MEM_PATTERN;
-  vm_phys_memset((phys_bytes) m_ptr->MEM_PTR, c, (phys_bytes) m_ptr->MEM_COUNT);
+  vm_memset(m_ptr->MEM_PROCESS, (phys_bytes) m_ptr->MEM_PTR,
+       c, (phys_bytes) m_ptr->MEM_COUNT);
   return(OK);
 }
 
index 9bd3073ebd1b8f3cb15a218e7299cdd2d49497d2..4f2c15759f10438992db11f8ee77d709e73a174f 100644 (file)
@@ -220,7 +220,6 @@ int elf_has_interpreter(char *exec_hdr,             /* executable header */
 
 int libexec_load_elf(struct exec_info *execi)
 {
-       int r;
        Elf_Ehdr *hdr = NULL;
        Elf_Phdr *phdr = NULL;
        int e, i = 0;
@@ -240,25 +239,26 @@ int libexec_load_elf(struct exec_info *execi)
         */
        i = elf_has_interpreter(execi->hdr, execi->hdr_len, NULL, 0);
        if(i > 0) {
-             printf("libexec: cannot load dynamically linked executable\n");
              return ENOEXEC;
        }
 
-       /* Make VM forget about all existing memory in process. */
-       vm_procctl(execi->proc_e, VMPPARAM_CLEAR);
-
        execi->stack_size = roundup(execi->stack_size, PAGE_SIZE);
        execi->stack_high = VM_STACKTOP;
        assert(!(VM_STACKTOP % PAGE_SIZE));
        stacklow = execi->stack_high - execi->stack_size;
 
+       assert(execi->copymem);
+       assert(execi->clearmem);
+       assert(execi->allocmem_prealloc);
+       assert(execi->allocmem_ondemand);
+
+       if(execi->clearproc) execi->clearproc(execi);
+
        for (i = 0; i < hdr->e_phnum; i++) {
                vir_bytes seg_membytes, page_offset, vaddr;
+               vir_bytes chunk, vfileend, vmemend;
                Elf_Phdr *ph = &phdr[i];
                if (ph->p_type != PT_LOAD || ph->p_memsz == 0) continue;
-#if 0
-               printf("index %d memsz 0x%lx vaddr 0x%lx\n", i, ph->p_memsz, ph->p_vaddr);
-#endif
                vaddr =  ph->p_vaddr;
                seg_membytes = ph->p_memsz;
                page_offset = vaddr % PAGE_SIZE;
@@ -268,34 +268,46 @@ int libexec_load_elf(struct exec_info *execi)
                if(first || startv > vaddr) startv = vaddr;
                first = 0;
 
-#if 0
-               printf("libexec_load_elf: mmap 0x%lx bytes at 0x%lx\n",
-                       seg_membytes, vaddr);
-#endif
-
-               /* Tell VM to make us some memory */
-               if(minix_mmap_for(execi->proc_e, (void *) vaddr, seg_membytes,
-                       PROT_READ|PROT_WRITE|PROT_EXEC,
-                       MAP_ANON|MAP_PREALLOC|MAP_FIXED, -1, 0) == MAP_FAILED) {
-                       printf("libexec_load_elf: mmap of 0x%lx bytes failed\n", seg_membytes);
-                       vm_procctl(execi->proc_e, VMPPARAM_CLEAR);
+               /* make us some memory */
+               if(execi->allocmem_prealloc(execi, vaddr, seg_membytes) != OK) {
+                       if(execi->clearproc) execi->clearproc(execi);
                        return ENOMEM;
                }
 
+#if ELF_DEBUG
+               printf("mmapped 0x%lx-0x%lx\n", vaddr, vaddr+seg_membytes);
+#endif
+
                /* Copy executable section into it */
-               if(execi->load(execi, ph->p_offset, ph->p_vaddr, ph->p_filesz) != OK) {
-                       printf("libexec_load_elf: load callback failed\n");
-                       vm_procctl(execi->proc_e, VMPPARAM_CLEAR);
+               if(execi->copymem(execi, ph->p_offset, ph->p_vaddr, ph->p_filesz) != OK) {
+                       if(execi->clearproc) execi->clearproc(execi);
                        return ENOMEM;
                }
+
+#if ELF_DEBUG
+               printf("copied 0x%lx-0x%lx\n", ph->p_vaddr, ph->p_vaddr+ph->p_filesz);
+#endif
+
+               /* Clear remaining bits */
+               vfileend  = ph->p_vaddr + ph->p_filesz;
+               vmemend = vaddr + seg_membytes;
+               if((chunk = ph->p_vaddr - vaddr) > 0) {
+#if ELF_DEBUG
+                       printf("start clearing 0x%lx-0x%lx\n", vaddr, vaddr+chunk);
+#endif
+                       execi->clearmem(execi, vaddr, chunk);
+               }
+               if((chunk = vmemend - vfileend) > 0) {
+#if ELF_DEBUG
+                       printf("end clearing 0x%lx-0x%lx\n", vfileend, vaddr+chunk);
+#endif
+                       execi->clearmem(execi, vfileend, chunk);
+               }
        }
 
        /* Make it a stack */
-       if(minix_mmap_for(execi->proc_e, (void *) stacklow, execi->stack_size,
-               PROT_READ|PROT_WRITE|PROT_EXEC,
-               MAP_ANON|MAP_FIXED, -1, 0) == MAP_FAILED) {
-               printf("libexec_load_elf: mmap for stack failed\n");
-               vm_procctl(execi->proc_e, VMPPARAM_CLEAR);
+       if(execi->allocmem_ondemand(execi, stacklow, execi->stack_size) != OK) {
+               if(execi->clearproc) execi->clearproc(execi);
                return ENOMEM;
        }
 
@@ -303,10 +315,6 @@ int libexec_load_elf(struct exec_info *execi)
        execi->pc = hdr->e_entry;
        execi->load_base = startv;
 
-       if((r = libexec_pm_newexec(execi->proc_e, execi)) != OK) {
-             printf("libexec_load_elf: pm_newexec failed: %d\n", r);
-       }
-
-       return(r);
+       return OK;
 }
 
index 4e5501584adf1b8b0a65d10a52bee261e8b00dac..1887c7f23ae34848afc292e37279545dbb740f0f 100644 (file)
 #include <minix/ipc.h>
 #include <minix/com.h>
 #include <minix/callnr.h>
+#include <minix/vm.h>
+#include <minix/syslib.h>
+#include <sys/mman.h>
 #include <machine/elf.h>
 
+int libexec_alloc_mmap_prealloc(struct exec_info *execi, off_t vaddr, size_t len)
+{
+       if(minix_mmap_for(execi->proc_e, (void *) vaddr, len,
+               PROT_READ|PROT_WRITE|PROT_EXEC,
+               MAP_ANON|MAP_PREALLOC|MAP_UNINITIALIZED|MAP_FIXED, -1, 0) == MAP_FAILED) {
+               return ENOMEM;
+       }
+
+       return OK;
+}
+
+int libexec_alloc_mmap_ondemand(struct exec_info *execi, off_t vaddr, size_t len)
+{
+       if(minix_mmap_for(execi->proc_e, (void *) vaddr, len,
+               PROT_READ|PROT_WRITE|PROT_EXEC,
+               MAP_ANON|MAP_FIXED, -1, 0) == MAP_FAILED) {
+               return ENOMEM;
+       }
+
+       return OK;
+}
+
+int libexec_clearproc_vm_procctl(struct exec_info *execi)
+{
+       return vm_procctl(execi->proc_e, VMPPARAM_CLEAR);
+}
+
+int libexec_clear_sys_memset(struct exec_info *execi, off_t vaddr, size_t len)
+{
+       return sys_memset(execi->proc_e, 0, vaddr, len);
+}
+
 void libexec_patch_ptr(char stack[ARG_MAX], vir_bytes base)
 {
 /* When doing an exec(name, argv, envp) call, the user builds up a stack
index 282dc4e4c6c4c88be0848f65c512b3c9e37a1323..613839c600637fb3a754d3e6810b9b31e398d1bb 100644 (file)
@@ -11,6 +11,11 @@ typedef int (*libexec_loadfunc_t)(struct exec_info *execi,
 typedef int (*libexec_clearfunc_t)(struct exec_info *execi,
        off_t vaddr, size_t len);
 
+typedef int (*libexec_allocfunc_t)(struct exec_info *execi,
+       off_t vaddr, size_t len);
+
+typedef int (*libexec_procclearfunc_t)(struct exec_info *execi);
+
 struct exec_info {
     /* Filled in by libexec caller */
     endpoint_t  proc_e;                 /* Process endpoint */
@@ -21,11 +26,16 @@ struct exec_info {
     uid_t new_uid;                      /* Process UID after exec */
     gid_t new_gid;                      /* Process GID after exec */
     int allow_setuid;                   /* Allow set{u,g}id execution? */
-    libexec_loadfunc_t load;           /* Load callback */
-    libexec_clearfunc_t clear;         /* Clear callback */
-    void *opaque;                      /* Callback data */
     vir_bytes stack_size;              /* Desired stack size */
 
+    /* Callback pointers for use by libexec */
+    libexec_loadfunc_t copymem;                /* Copy callback */
+    libexec_clearfunc_t clearmem;      /* Clear callback */
+    libexec_allocfunc_t allocmem_prealloc; /* Alloc callback */
+    libexec_allocfunc_t allocmem_ondemand; /* Alloc callback */
+    libexec_procclearfunc_t clearproc; /* Clear process callback */
+    void *opaque;                      /* Callback data */
+
     /* Filled in by libexec load function */
     vir_bytes load_base;               /* Where executable is loaded */
     vir_bytes pc;                       /* Entry point of exec file */
@@ -45,7 +55,11 @@ void libexec_patch_ptr(char stack[ARG_MAX], vir_bytes base);
 int libexec_pm_newexec(endpoint_t proc_e, struct exec_info *execi);
 
 typedef int (*libexec_exec_loadfunc_t)(struct exec_info *execi);
-
 int libexec_load_elf(struct exec_info *execi);
 
+int libexec_alloc_mmap_prealloc(struct exec_info *execi, off_t vaddr, size_t len);
+int libexec_alloc_mmap_ondemand(struct exec_info *execi, off_t vaddr, size_t len);
+int libexec_clearproc_vm_procctl(struct exec_info *execi);
+int libexec_clear_sys_memset(struct exec_info *execi, off_t vaddr, size_t len);
+
 #endif /* !_LIBEXEC_H_ */
index 483ec032fd9c9d51b39154bed0e21932f235b761..65e6590ab8eab5df6cf4a39379c8c77f51f55db3 100644 (file)
@@ -1,6 +1,7 @@
 #include "syslib.h"
 
-int sys_memset(unsigned long pattern, phys_bytes base, phys_bytes bytes)
+int sys_memset(endpoint_t who, unsigned long pattern,
+       phys_bytes base, phys_bytes bytes)
 {
 /* Zero a block of data.  */
   message mess;
@@ -10,6 +11,7 @@ int sys_memset(unsigned long pattern, phys_bytes base, phys_bytes bytes)
   mess.MEM_PTR = (char *) base;
   mess.MEM_COUNT   = bytes;
   mess.MEM_PATTERN = pattern;
+  mess.MEM_PROCESS = who;
 
   return(_kernel_call(SYS_MEMSET, &mess));
 }
index 3eaad4ec77030e550da572a688dafb35cd1efd3e..1a9cbadfa990032cd647e6469a97ee18e6eefa05 100644 (file)
@@ -126,7 +126,13 @@ static int do_exec(int proc_e, char *exec, size_t exec_len, char *progname,
        strncpy(execi.progname, progname, PROC_NAME_LEN-1);
        execi.progname[PROC_NAME_LEN-1] = '\0';
        execi.frame_len = frame_len;
-       execi.load = read_seg;
+
+       /* callback functions and data */
+       execi.copymem = read_seg;
+       execi.clearproc = libexec_clearproc_vm_procctl;
+       execi.clearmem = libexec_clear_sys_memset;
+       execi.allocmem_prealloc = libexec_alloc_mmap_prealloc;
+       execi.allocmem_ondemand = libexec_alloc_mmap_ondemand;
 
        for(i = 0; exec_loaders[i].load_object != NULL; i++) {
            r = (*exec_loaders[i].load_object)(&execi);
@@ -140,6 +146,10 @@ static int do_exec(int proc_e, char *exec, size_t exec_len, char *progname,
            return r;
        }
 
+       /* Inform PM */
+        if((r = libexec_pm_newexec(execi.proc_e, &execi)) != OK)
+               return r;
+
        /* Patch up stack and copy it from RS to new core image. */
        vsp = execi.stack_high;
        vsp -= frame_len;
@@ -194,7 +204,7 @@ size_t seg_bytes           /* how much is to be transferred? */
   if (off+seg_bytes > execi->hdr_len) return ENOEXEC;
   if((r= sys_vircopy(SELF, D, ((vir_bytes)execi->hdr)+off,
        execi->proc_e, D, seg_addr, seg_bytes)) != OK) {
-       printf("RS: exec read_seg: copy 0x%lx bytes into %d at 0x%lx failed: %d\n",
+       printf("RS: exec read_seg: copy 0x%x bytes into %d at 0x%lx failed: %d\n",
                seg_bytes, execi->proc_e, seg_addr, r);
   }
   return r;
index 9a363e22448a1f96ca44ad5f5a46bebaf58ad32c..3e490777fff0b9bbc9cda7d5317fd93a984b30b6 100644 (file)
@@ -296,9 +296,14 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
        Get_read_vp(execi, fullpath, 0, 0, &resolve, fp);
   }
 
+  /* callback functions and data */
+  execi.args.copymem = read_seg;
+  execi.args.clearproc = libexec_clearproc_vm_procctl;
+  execi.args.clearmem = libexec_clear_sys_memset;
+  execi.args.allocmem_prealloc = libexec_alloc_mmap_prealloc;
+  execi.args.allocmem_ondemand = libexec_alloc_mmap_ondemand;
   execi.args.opaque = &execi;
-  execi.args.load = &read_seg;
-  execi.args.clear = NULL;
+
   execi.args.proc_e = proc_e;
   execi.args.frame_len = frame_len;
 
@@ -310,6 +315,9 @@ int pm_exec(endpoint_t proc_e, vir_bytes path, size_t path_len,
 
   FAILCHECK(r);
 
+  /* Inform PM */
+  FAILCHECK(libexec_pm_newexec(proc_e, &execi.args));
+
   /* Save off PC */
   *pc = execi.args.pc;
 
index 37ceb5b926c8436d436162b81943a7518b5a52d6..68a5c11e676479d0ae1bd8973f7fd08fd18f6a57 100644 (file)
@@ -506,7 +506,7 @@ static phys_bytes alloc_pages(int pages, int memflags, phys_bytes *len)
 
        if(memflags & PAF_CLEAR) {
                int s;
-               if ((s= sys_memset(0, CLICK_SIZE*mem,
+               if ((s= sys_memset(NONE, 0, CLICK_SIZE*mem,
                        VM_PAGE_SIZE*pages)) != OK) 
                        panic("alloc_mem: sys_memset failed: %d", s);
        }
@@ -543,7 +543,7 @@ static void free_pages(phys_bytes pageno, int npages)
        assert(!addr_search(&addravl, pageno, AVL_EQUAL));
 
 #if JUNKFREE
-       if(sys_memset(0xa5a5a5a5, VM_PAGE_SIZE * pageno,
+       if(sys_memset(NONE, 0xa5a5a5a5, VM_PAGE_SIZE * pageno,
                VM_PAGE_SIZE * npages) != OK)
                        panic("free_pages: sys_memset failed");
 #endif
index 4b1141f995d79d28b8c866b232b53be1c44b7688..2110cccda91de3e39a73c2e9f6327bd30e91ec16 100644 (file)
@@ -42,11 +42,14 @@ int do_mmap(message *m)
        int mfflags = 0;
        vir_bytes addr;
        struct vir_region *vr = NULL;
+       int execpriv = 0;
+
+       /* RS and VFS can do slightly more special mmap() things */
+       if(m->m_source == VFS_PROC_NR || m->m_source == RS_PROC_NR)
+               execpriv = 1;
 
        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(!execpriv) return EPERM;
                if((r=vm_isokendpt(m->VMM_FORWHOM, &n)) != OK)
                        return ESRCH;
        } else {
@@ -79,6 +82,10 @@ int do_mmap(message *m)
                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_IPC_SHARED) {
                        vrflags |= VR_SHARED;
                        /* Shared memory has to be preallocated. */
index 744ad3ee6dd0996b79130bbfefd992762f085154..e315107298912a14f5f30082cc6ddc7a834fac55 100644 (file)
@@ -583,6 +583,11 @@ USE(newregion,
                }
        }
 
+       /* Pre-allocations should be uninitialized, but after that it's a
+        * different story.
+        */
+       newregion->flags &= ~VR_UNINITIALIZED;
+
        /* Link it. */
        region_insert(&vmp->vm_regions_avl, newregion);
 
@@ -1266,6 +1271,11 @@ int write;
        struct phys_region *physr, *nextphysr;
        int changes = 0;
        physr_iter iter;
+       u32_t allocflags = 0;
+
+       if(!(region->flags & VR_UNINITIALIZED)) {
+               allocflags = PAF_CLEAR;
+       }
 
 #define FREE_RANGE_HERE(er1, er2) {                                    \
        struct phys_region *r1 = (er1), *r2 = (er2);                    \
@@ -1277,7 +1287,7 @@ int write;
        if(start < end) {                                               \
                SANITYCHECK(SCL_DETAIL);                                \
                if(map_new_physblock(vmp, region, start,                \
-                       end-start, MAP_NONE, PAF_CLEAR, 0) != OK) {     \
+                       end-start, MAP_NONE, allocflags, 0) != OK) {    \
                        SANITYCHECK(SCL_DETAIL);                        \
                        return ENOMEM;                                  \
                }                                                       \
index cace7a819a6b22a3e3efa8b1b5afd9904d86374b..a5d09b068403c15c5eb1512f2570603acb61d57c 100644 (file)
@@ -55,6 +55,7 @@ typedef struct vir_region {
 #define VR_LOWER1MB    0x010
 #define VR_CONTIG      0x020   /* Must be physically contiguous. */
 #define VR_SHARED      0x040
+#define VR_UNINITIALIZED 0x080 /* Do not clear after allocation  */
 
 /* Mapping type: */
 #define VR_ANON                0x100   /* Memory to be cleared and allocated */