Deputizes env.c. Update your Ivy!
authorZach Anderson <zra@cs.berkeley.edu>
Sun, 7 Jun 2009 20:53:59 +0000 (13:53 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sun, 7 Jun 2009 20:56:50 +0000 (13:56 -0700)
Annotates env.c and includes.  There are still a few TODOs.  Barret
added a couple things to make it work with some of the changes already
on master (UGDATA, run_env_handler).

include/arch/mmu.h
include/env.h
include/pmap.h
include/ros/env.h
include/ros/queue.h
kern/src/env.c

index 43d35d1..b7f3c54 100644 (file)
@@ -44,7 +44,7 @@
 #define JPGOFF(la)     (((uintptr_t) (la)) & 0x003FFFFF)
 
 // construct linear address from indexes and offset
-#define PGADDR(d, t, o)        ((void*) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
+#define PGADDR(d, t, o)        ((void*SNT) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
 
 // Page directory and page table constants.
 #define NPDENTRIES     1024            // page directory entries per page directory
index 4ac2bb0..cb1b577 100644 (file)
@@ -7,7 +7,7 @@
 #include <ros/env.h>
 #include <ros/error.h>
 
-extern env_t *envs;            // All environments
+extern env_t *COUNT(NENV) envs;                // All environments
 extern uint32_t num_envs;              // Number of envs
 extern env_t* NORACE curenvs[MAX_NUM_CPUS];
 
@@ -15,11 +15,11 @@ LIST_HEAD(env_list_t, env_t);               // Declares 'struct Env_list'
 
 void   env_init(void);
 int            env_alloc(env_t **e, envid_t parent_id);
-void   env_free(env_t *e);
+void   env_free(env_t *SAFE e);
 error_t        env_incref(env_t* e);
-void   env_decref(env_t* e);
-env_t* env_create(uint8_t *binary, size_t size);
-void   (IN_HANDLER env_destroy)(env_t *e);     // Does not return if e == curenv
+void   env_decref(env_t *SAFE e);
+env_t* env_create(uint8_t *COUNT(size) binary, size_t size);
+void   (IN_HANDLER env_destroy)(env_t *SAFE e);        // Does not return if e == curenv
 
 int    envid2env(envid_t envid, env_t **env_store, bool checkperm);
 // The following two functions do not return
index f899f04..f24d756 100644 (file)
@@ -35,7 +35,7 @@
        uint32_t __m_ppn = PPN(__m_pa);                         \
        if (__m_ppn >= npage)                                   \
                warn("KADDR called with invalid pa %08lx", __m_pa);\
-       (void*) (__m_pa + KERNBASE);                            \
+       (void*TRUSTED) (__m_pa + KERNBASE);                             \
 })
 
 /*
@@ -67,11 +67,11 @@ struct Page {
 
 extern char bootstacktop[], bootstack[];
 
-extern page_t *pages;
+extern page_t *COUNT(npage) pages;
 extern size_t npage;
 
 extern physaddr_t boot_cr3;
-extern pde_t *boot_pgdir;
+extern pde_t *COUNT(NPDENTRIES) boot_pgdir;
 
 extern segdesc_t (COUNT(SEG_COUNT) gdt)[];
 extern pseudodesc_t gdt_pd;
@@ -85,14 +85,14 @@ void        page_init(void);
 void   page_check(void);
 int    page_alloc(page_t **pp_store);
 void   page_free(page_t *pp);
-int    page_insert(pde_t *pgdir, page_t *pp, void *va, int perm);
-void   page_remove(pde_t *pgdir, void *va);
-page_t *page_lookup(pde_t *pgdir, void *va, pte_t **pte_store);
-error_t        pagetable_remove(pde_t *pgdir, void *va);
+int    page_insert(pde_t *COUNT(NPDENTRIES) pgdir, page_t *pp, void *SNT va, int perm);
+void   page_remove(pde_t *COUNT(NPDENTRIES) pgdir, void *SNT va);
+page_t *page_lookup(pde_t *COUNT(NPDENTRIES) pgdir, void *va, pte_t **pte_store);
+error_t        pagetable_remove(pde_t *COUNT(NPDENTRIES) pgdir, void *va);
 void   page_decref(page_t *pp);
 
 void setup_default_mtrrs(barrier_t* smp_barrier);
-void   tlb_invalidate(pde_t *pgdir, void *va);
+void   tlb_invalidate(pde_t *COUNT(NPDENTRIES) pgdir, void *va);
 void tlb_flush_global(void);
 
 void *COUNT(len)
@@ -128,11 +128,11 @@ static inline page_t* pa2page(physaddr_t pa)
        return &pages[PPN(pa)];
 }
 
-static inline void* page2kva(page_t *pp)
+static inline void*COUNT(PGSIZE) page2kva(page_t *pp)
 {
        return KADDR(page2pa(pp));
 }
 
-pte_t *pgdir_walk(pde_t *pgdir, const void *va, int create);
+pte_t *pgdir_walk(pde_t *COUNT(NPDENTRIES) pgdir, const void *SNT va, int create);
 
 #endif /* !ROS_KERN_PMAP_H */
index 3744046..81dcf40 100644 (file)
@@ -42,7 +42,7 @@ typedef int32_t envid_t;
 #define ENV_DYING                      4
 
 struct Env {
-       LIST_ENTRY(env_t) env_link;     // Free list link pointers
+       LIST_ENTRY(env_t) env_link NOINIT;      // Free list link pointers
        uint32_t lock;
        trapframe_t env_tf;                     // Saved registers
        envid_t env_id;                         // Unique environment identifier
@@ -54,11 +54,12 @@ struct Env {
        syscall_back_ring_t env_sysbackring;    // BackRing for generic syscalls
 
        // Address space
-       pde_t *env_pgdir;                       // Kernel virtual address of page dir
+       pde_t *COUNT(NPDENTRIES) env_pgdir;                     // Kernel virtual address of page dir
        physaddr_t env_cr3;                     // Physical address of page dir
        // TODO - give these two proper types (pointers to structs)
-       void* env_procinfo;             // KVA of per-process shared info table (RO)
-       void* env_procdata;             // KVA of per-process shared data table (RW)
+       // TODO - not always going to be PGSIZE either!
+       void*COUNT(PGSIZE) env_procinfo;                // KVA of per-process shared info table (RO)
+       void*COUNT(PGSIZE) env_procdata;                // KVA of per-process shared data table (RW)
        // Eventually want to move this to a per-system shared-info page
        uint64_t env_tscfreq;           // Frequency of the TSC for measurements
 };
index 1102ed4..c62fae3 100644 (file)
@@ -108,8 +108,8 @@ LIST_INSERT_HEAD(&flist, g, frob_link);     /* add g as first element in list */
  */
 #define        LIST_HEAD(name, type)                                   \
 typedef struct {                                                               \
-       type *lh_first; /* first element */                     \
-       type *lh_last;  /* last element */                      \
+       type *SAFE lh_first;    /* first element */                     \
+       type *SAFE lh_last;     /* last element */                      \
 } name;
 
 /*
@@ -129,8 +129,8 @@ typedef struct {                                                            \
  */
 #define        LIST_ENTRY(type)                                                \
 struct {                                                               \
-       type *le_next;  /* next element */                      \
-       type **le_prev; /* ptr to ptr to this element */        \
+       type *le_next NOINIT;   /* next element */                      \
+       type **le_prev NOINIT;  /* ptr to ptr to this element */        \
 }
 
 /*
index 77c6d44..6c0838c 100644 (file)
@@ -1,6 +1,7 @@
 /* See COPYRIGHT for copyright information. */
 #ifdef __DEPUTY__
-#pragma nodeputy
+//#pragma nodeputy
+#pragma noasync
 #endif
 
 #include <arch/x86.h>
@@ -108,6 +109,8 @@ env_init(void)
 //
 static int
 env_setup_vm(env_t *e)
+WRITES(e->env_pgdir, e->env_cr3, e->env_procinfo, e->env_procdata,
+       e->env_sysbackring)
 {
        int i, r;
        page_t *pgdir = NULL, *pginfo = NULL, *pgdata = NULL;
@@ -150,9 +153,10 @@ env_setup_vm(env_t *e)
        memset(e->env_procdata, 0, PGSIZE);
 
        // Initialize the generic syscall ring buffer
-       SHARED_RING_INIT((syscall_sring_t*)e->env_procdata);
+       SHARED_RING_INIT((syscall_sring_t *SAFE)e->env_procdata);
        // Initialize the backend of the ring buffer
-       BACK_RING_INIT(&e->env_sysbackring, (syscall_sring_t*)e->env_procdata, PGSIZE);
+       BACK_RING_INIT(&e->env_sysbackring, (syscall_sring_t *SAFE)e->env_procdata,
+                      PGSIZE);
 
        // should be able to do this so long as boot_pgdir never has
        // anything put below UTOP
@@ -173,8 +177,8 @@ env_setup_vm(env_t *e)
        // the kernel wants to keep pointers to it easily.
        // Could place all of this with a function that maps a shared memory page
        // that can work between any two address spaces or something.
-       r = page_insert(e->env_pgdir, pginfo, (void*)UINFO, PTE_U);
-       r = page_insert(e->env_pgdir, pgdata, (void*)UDATA, PTE_U | PTE_W);
+       r = page_insert(e->env_pgdir, pginfo, (void*SNT)UINFO, PTE_U);
+       r = page_insert(e->env_pgdir, pgdata, (void*SNT)UDATA, PTE_U | PTE_W);
        if (r < 0) {
                // note that we can't currently deallocate the pages created by
                // pgdir_walk (inside insert).  should be able to gather them up when
@@ -198,7 +202,7 @@ env_setup_vm(env_t *e)
        shared_page->pp_ref++;
 
        // Inserted into every process's address space at UGDATA
-       page_insert(e->env_pgdir, shared_page, (void*)UGDATA, PTE_U | PTE_W);
+       page_insert(e->env_pgdir, shared_page, (void*SNT)UGDATA, PTE_U | PTE_W);
 
        return 0;
 }
@@ -221,7 +225,9 @@ env_alloc(env_t **newenv_store, envid_t parent_id)
        if (!(e = LIST_FIRST(&env_free_list)))
                return -E_NO_FREE_ENV;
        
-       memset((void*)e + sizeof(e->env_link), 0, sizeof(*e) - sizeof(e->env_link));
+       //memset((void*)e + sizeof(e->env_link), 0, sizeof(*e) - sizeof(e->env_link));
+
+    { INITSTRUCT(*e)
 
        // Allocate and set up the page directory for this environment.
        if ((r = env_setup_vm(e)) < 0)
@@ -234,6 +240,7 @@ env_alloc(env_t **newenv_store, envid_t parent_id)
        e->env_id = generation | (e - envs);
 
        // Set the basic status variables.
+    e->lock = 0;
        e->env_parent_id = parent_id;
        e->env_status = ENV_RUNNABLE;
        e->env_runs = 0;
@@ -274,6 +281,7 @@ env_alloc(env_t **newenv_store, envid_t parent_id)
        env_t* curenv = curenvs[lapic_get_id()];
 
        printk("[%08x] new env %08x\n", curenv ? curenv->env_id : 0, e->env_id);
+       } // INIT_STRUCT
        return 0;
 }
 
@@ -285,9 +293,9 @@ env_alloc(env_t **newenv_store, envid_t parent_id)
 // Panic if any allocation attempt fails.
 //
 static void
-segment_alloc(env_t *e, void *va, size_t len)
+segment_alloc(env_t *e, void *SNT va, size_t len)
 {
-       void *start, *end;
+       void *SNT start, *SNT end;
        size_t num_pages;
        int i, r;
        page_t *page;
@@ -340,7 +348,7 @@ segment_alloc(env_t *e, void *va, size_t len)
 //  - How might load_icode fail?  What might be wrong with the given input?
 //
 static void
-load_icode(env_t *e, uint8_t *binary, size_t size)
+load_icode(env_t *e, uint8_t *COUNT(size) binary, size_t size)
 {
        // Hints:
        //  Load each program segment into virtual memory
@@ -385,13 +393,16 @@ load_icode(env_t *e, uint8_t *binary, size_t size)
        // mappings for the kernel as does boot_pgdir
        lcr3(e->env_cr3);
 
+       // TODO: how do we do a runtime COUNT?
        proghdr_t *phdr = (proghdr_t *)(binary + elfhdr->e_phoff);
-       for (i = 0; i < elfhdr->e_phnum; i++, phdr++) {
+       for (i = 0; i < elfhdr->e_phnum; i++, phdr++) { TRUSTEDBLOCK
+        // zra: TRUSTEDBLOCK until validation is done.
                if (phdr->p_type != ELF_PROG_LOAD)
                        continue;
+        // TODO: validate elf header fields!
                // seg alloc creates PTE_U|PTE_W pages.  if you ever want to change
                // this, there will be issues with overlapping sections
-               segment_alloc(e, (void*)phdr->p_va, phdr->p_memsz);
+               segment_alloc(e, (void*SNT)phdr->p_va, phdr->p_memsz);
                memcpy((void*)phdr->p_va, binary + phdr->p_offset, phdr->p_filesz);
                memset((void*)phdr->p_va + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
        }
@@ -401,7 +412,7 @@ load_icode(env_t *e, uint8_t *binary, size_t size)
        // Now map one page for the program's initial stack
        // at virtual address USTACKTOP - PGSIZE.
 
-       segment_alloc(e, (void*)(USTACKTOP - PGSIZE), PGSIZE);
+       segment_alloc(e, (void*SNT)(USTACKTOP - PGSIZE), PGSIZE);
 }
 
 //
@@ -442,7 +453,7 @@ env_free(env_t *e)
 
                // find the pa and va of the page table
                pa = PTE_ADDR(e->env_pgdir[pdeno]);
-               pt = (pte_t*) KADDR(pa);
+               pt = (pte_t*COUNT(NPTENTRIES)) KADDR(pa);
 
                // unmap all PTEs in this page table
                for (pteno = 0; pteno <= PTX(~0); pteno++) {
@@ -620,7 +631,9 @@ void run_env_handler(trapframe_t *tf, void* data)
        assert(data);
        per_cpu_info_t *cpuinfo = &per_cpu_info[lapic_get_id()];
        spin_lock_irqsave(&cpuinfo->lock);
+       { TRUSTEDBLOCK // TODO: how do we make this func_t cast work?
        cpuinfo->delayed_work.func = (func_t)env_run;
        cpuinfo->delayed_work.data = data;
+       }
        spin_unlock_irqsave(&cpuinfo->lock);
 }