VMMCP: initialization
[akaros.git] / kern / src / env.c
index f59e175..5187e9d 100644 (file)
@@ -6,10 +6,9 @@
 
 #include <arch/arch.h>
 #include <arch/mmu.h>
-#include <arch/bitmask.h>
+#include <bitmask.h>
 #include <elf.h>
 #include <smp.h>
-
 #include <atomic.h>
 #include <string.h>
 #include <assert.h>
@@ -44,12 +43,10 @@ WRITES(e->env_pgdir, e->env_cr3, e->procinfo, e->procdata)
        page_t *pgdir = NULL;
        static page_t * RO shared_page = 0;
 
-       /*
-        * First, allocate a page for the pgdir of this process and up
-        * its reference count since this will never be done elsewhere
-        */
+       /* Get a page for the pgdir.  Storing the ref in pgdir/env_pgdir */
        r = kpage_alloc(&pgdir);
-       if(r < 0) return r;
+       if (r < 0)
+               return r;
 
        /*
         * Next, set up the e->env_pgdir and e->env_cr3 pointers to point
@@ -66,7 +63,7 @@ WRITES(e->env_pgdir, e->env_cr3, e->procinfo, e->procdata)
 
        // Map in the kernel to the top of every address space
        // should be able to do this so long as boot_pgdir never has
-       // anything put below UTOP
+       // anything put below ULIM
        // TODO check on this!  had a nasty bug because of it
        // this is a bit wonky, since if it's not PGSIZE, lots of other things are
        // screwed up...
@@ -74,8 +71,10 @@ WRITES(e->env_pgdir, e->env_cr3, e->procinfo, e->procdata)
 
        // VPT and UVPT map the env's own page table, with
        // different permissions.
+       #ifndef NOVPT
        e->env_pgdir[PDX(VPT)]  = PTE(LA2PPN(e->env_cr3), PTE_P | PTE_KERN_RW);
        e->env_pgdir[PDX(UVPT)] = PTE(LA2PPN(e->env_cr3), PTE_P | PTE_USER_RO);
+       #endif
 
        /* These need to be contiguous, so the kernel can alias them.  Note the
         * pages return with a refcnt, but it's okay to insert them since we free
@@ -84,6 +83,8 @@ WRITES(e->env_pgdir, e->env_cr3, e->procinfo, e->procdata)
                goto env_setup_vm_error_i;
        if (!(e->procdata = get_cont_pages(LOG2_UP(PROCDATA_NUM_PAGES), 0)))
                goto env_setup_vm_error_d;
+       /* Normally we'd 0 the pages here.  We handle it in proc_init_proc*.  Don't
+        * start the process without calling those. */
        for (int i = 0; i < PROCINFO_NUM_PAGES; i++) {
                if (page_insert(e->env_pgdir, kva2page((void*)e->procinfo + i *
                                PGSIZE), (void*SNT)(UINFO + i*PGSIZE), PTE_USER_RO) < 0)
@@ -94,25 +95,17 @@ WRITES(e->env_pgdir, e->env_cr3, e->procinfo, e->procdata)
                                PGSIZE), (void*SNT)(UDATA + i*PGSIZE), PTE_USER_RW) < 0)
                        goto env_setup_vm_error;
        }
-       memset(e->procinfo, 0, sizeof(struct procinfo));
-       memset(e->procdata, 0, sizeof(struct procdata));
-
-       /* Finally, set up the Global Shared Data page for all processes.
-        * Can't be trusted, but still very useful at this stage for us.
-        * Consider removing when we have real processes.
-        * (TODO).  Note the page is alloced only the first time through
-        */
+       /* Finally, set up the Global Shared Data page for all processes.  Can't be
+        * trusted, but still very useful at this stage for us.  Consider removing
+        * when we have real processes (TODO). 
+        *
+        * Note the page is alloced only the first time through, and its ref is
+        * stored in shared_page. */
        if (!shared_page) {
-               if(upage_alloc(e, &shared_page,1) < 0)
+               if (upage_alloc(e, &shared_page, 1) < 0)
                        goto env_setup_vm_error;
-               // Up it, so it never goes away.  One per user, plus one from page_alloc
-               // This is necessary, since it's in the per-process range of memory that
-               // gets freed during page_free.
-               __kref_get(&shared_page->pg_kref, 1);
        }
-
-       // Inserted into every process's address space at UGDATA
-       if(page_insert(e->env_pgdir, shared_page, (void*SNT)UGDATA, PTE_USER_RW) < 0)
+       if (page_insert(e->env_pgdir, shared_page, (void*)UGDATA, PTE_USER_RW) < 0)
                goto env_setup_vm_error;
 
        return 0;
@@ -144,17 +137,14 @@ void env_user_mem_free(env_t* e, void* start, size_t len)
        assert((uintptr_t)start + len <= UVPT); //since this keeps fucking happening
        int user_page_free(env_t* e, pte_t* pte, void* va, void* arg)
        {
-               if(PAGE_PRESENT(*pte))
-               {
-                       page_t* page = ppn2page(PTE2PPN(*pte));
-                       *pte = 0;
-                       page_decref(page);
-               } else {
-                       assert(PAGE_PAGED_OUT(*pte));
-                       /* TODO: (SWAP) deal with this */
-                       panic("Swapping not supported!");
-                       *pte = 0;
-               }
+               if (!PAGE_PRESENT(*pte))
+                       return 0;
+               page_t *page = ppn2page(PTE2PPN(*pte));
+               *pte = 0;
+               page_decref(page);
+               /* TODO: consider other states here (like !P, yet still tracking a page,
+                * for VM tricks, page map stuff, etc.  Should be okay: once we're
+                * freeing, everything else about this proc is dead. */
                return 0;
        }