Fixed env_segment_free bug
authorAndrew Waterman <waterman@r53.millennium.berkeley.edu>
Mon, 26 Oct 2009 10:43:19 +0000 (03:43 -0700)
committerAndrew Waterman <waterman@r53.millennium.berkeley.edu>
Mon, 26 Oct 2009 10:43:19 +0000 (03:43 -0700)
We called page_decref rather than page_remove, so PTEs weren't zeroed.

kern/arch/i386/mmu.h
kern/arch/i386/page_alloc.c
kern/arch/sparc/mmu.h
kern/arch/sparc/page_alloc.c
kern/include/pmap.h
kern/src/env.c
kern/src/manager.c
kern/src/page_alloc.c
kern/src/pmap.c
user/parlib/src/newlib_backend.c

index aca9c44..a008a78 100644 (file)
@@ -33,7 +33,8 @@
 // use PGADDR(PDX(la), PTX(la), PGOFF(la)).
 
 // page number field of address
-#define PPN(la)                (((uintptr_t) (la)) >> PTXSHIFT)
+#define LA2PPN(la)     (((uintptr_t) (la)) >> PTXSHIFT)
+#define PTE2PPN(pte)   LA2PPN(pte)
 #define VPN(la)                PPN(la)         // used to index into vpt[]
 
 // page directory index
index feb13ef..0ab6c1c 100644 (file)
@@ -65,7 +65,7 @@ void page_alloc_init()
        // alloc the second page, since we will need it later to init the other cores
        // probably need to be smarter about what page we use (make this dynamic) TODO
        pages[1].page_ref = 1;
-       for (i = 2; i < PPN(IOPHYSMEM); i++) {
+       for (i = 2; i < LA2PPN(IOPHYSMEM); i++) {
                pages[i].page_ref = 0;
                LIST_INSERT_HEAD(
                   &(colored_page_free_list[get_page_color(page2ppn(&pages[i]), 
@@ -74,13 +74,13 @@ void page_alloc_init()
                   page_link
                );
        }
-       for (i = PPN(IOPHYSMEM); i < PPN(EXTPHYSMEM); i++) {
+       for (i = LA2PPN(IOPHYSMEM); i < LA2PPN(EXTPHYSMEM); i++) {
                pages[i].page_ref = 1;
        }
-       for (i = PPN(EXTPHYSMEM); i < PPN(physaddr_after_kernel); i++) {
+       for (i = LA2PPN(EXTPHYSMEM); i < LA2PPN(physaddr_after_kernel); i++) {
                pages[i].page_ref = 1;
        }
-       for (i = PPN(physaddr_after_kernel); i < PPN(maxaddrpa); i++) {
+       for (i = LA2PPN(physaddr_after_kernel); i < LA2PPN(maxaddrpa); i++) {
                pages[i].page_ref = 0;
                LIST_INSERT_HEAD(
                   &(colored_page_free_list[get_page_color(page2ppn(&pages[i]), 
@@ -91,7 +91,7 @@ void page_alloc_init()
        }
        // this block out all memory above maxaddrpa.  will need another mechanism
        // to allocate and map these into the kernel address space
-       for (i = PPN(maxaddrpa); i < npages; i++) {
+       for (i = LA2PPN(maxaddrpa); i < npages; i++) {
                pages[i].page_ref = 1;
        }
        printk("Page alloc init successful\n");
index 38b06fb..c0ab4cb 100644 (file)
 // and PGOFF(la), use PGADDR(L1X(la), L2X(la), L3X(la), PGOFF(la)).
 
 // page number field of address
-#define PPN(la)                (((uintptr_t) (la)) >> L3PGSHIFT)
+#define LA2PPN(la)     (((uintptr_t) (la)) >> L3PGSHIFT)
+
+// page number field of PPN
+#define PTE2PPN(pte)   (((uintptr_t) (pte)) >> 8)
 
 // index into L1 PT
 #define L1X(la)                ((((uintptr_t) (la)) >> L1PGSHIFT) & 0xFF)
index ad247b2..8e46878 100644 (file)
@@ -63,11 +63,11 @@ void page_alloc_init()
        physaddr_t physaddr_after_kernel = PADDR(ROUNDUP(boot_freemem, PGSIZE));
 
        // mark [0, physaddr_after_kernel) as in-use
-       for(i = 0; i < PPN(physaddr_after_kernel); i++)
+       for(i = 0; i < LA2PPN(physaddr_after_kernel); i++)
                pages[i].page_ref = 1;
 
        // mark [physaddr_after_kernel, maxaddrpa) as free
-       for(i = PPN(physaddr_after_kernel); i < PPN(maxaddrpa); i++)
+       for(i = LA2PPN(physaddr_after_kernel); i < LA2PPN(maxaddrpa); i++)
        {
                pages[i].page_ref = 0;
                 LIST_INSERT_HEAD(
@@ -79,7 +79,7 @@ void page_alloc_init()
        }
 
        // mark [maxaddrpa, ...) as in-use (as they are invalid)
-       for(i = PPN(maxaddrpa); i < npages; i++)
+       for(i = LA2PPN(maxaddrpa); i < npages; i++)
                pages[i].page_ref = 1;
 }
 
index 0f6d8c2..8e056aa 100644 (file)
@@ -44,7 +44,7 @@
 #define KADDR(pa)                                              \
 ({                                                             \
        physaddr_t __m_pa = (pa);                               \
-       size_t __m_ppn = PPN(__m_pa);                           \
+       size_t __m_ppn = LA2PPN(__m_pa);                        \
        if (__m_ppn >= npages)                                  \
                warn("KADDR called with invalid pa %08lx", __m_pa);\
        (void*TRUSTED) (__m_pa + KERNBASE);                             \
@@ -123,9 +123,9 @@ static inline physaddr_t page2pa(page_t *pp)
 
 static inline page_t*COUNT(1) pa2page(physaddr_t pa)
 {
-       if (PPN(pa) >= npages)
+       if (LA2PPN(pa) >= npages)
                warn("pa2page called with pa (0x%08x) larger than npages", pa);
-       return &pages[PPN(pa)];
+       return &pages[LA2PPN(pa)];
 }
 
 static inline void*COUNT(PGSIZE) page2kva(page_t *pp)
index 1da01c5..8c1edaf 100644 (file)
@@ -163,8 +163,8 @@ WRITES(e->env_pgdir, e->env_cr3, e->env_procinfo, e->env_procdata)
 
        // VPT and UVPT map the env's own page table, with
        // different permissions.
-       e->env_pgdir[PDX(VPT)]  = PTE(PPN(e->env_cr3), PTE_P | PTE_KERN_RW);
-       e->env_pgdir[PDX(UVPT)] = PTE(PPN(e->env_cr3), PTE_P | PTE_USER_RO);
+       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);
 
        /*
         * Now allocate and insert all pages required for the shared
@@ -354,7 +354,7 @@ env_segment_alloc(env_t *e, void *SNT va, size_t len)
        // page_insert/pgdir_walk alloc a page and read/write to it via its address
        // starting from pgdir (e's), so we need to be using e's pgdir
        assert(e->env_cr3 == rcr3());
-       num_pages = PPN(end - start);
+       num_pages = LA2PPN(end - start);
 
        for (i = 0; i < num_pages; i++, start += PGSIZE) {
                // skip if a page is already mapped.  yes, page_insert will page_remove
@@ -388,13 +388,13 @@ env_segment_free(env_t *e, void *SNT va, size_t len)
        // page_insert/pgdir_walk alloc a page and read/write to it via its address
        // starting from pgdir (e's), so we need to be using e's pgdir
        assert(e->env_cr3 == rcr3());
-       num_pages = PPN(end - start);
+       num_pages = LA2PPN(end - start);
 
        for (int i = 0; i < num_pages; i++, start += PGSIZE) {
                // skip if a page is already unmapped. 
                pte = pgdir_walk(e->env_pgdir, start, 0);
                if (pte && *pte & PTE_P)
-                       page_decref(ppn2page(PPN(*pte)));
+                       page_remove(e->env_pgdir,start);
        }
 }
 
index c20ddbe..83346e6 100644 (file)
@@ -191,6 +191,9 @@ void manager_klueska()
                proc_set_state(envs[0], PROC_RUNNABLE_S);
                proc_run(envs[0]);
        }
+       schedule();
+
+       panic("DON'T PANIC");
 }
 
 void manager_waterman()
@@ -205,21 +208,18 @@ void manager_waterman()
                        envs[0] = kfs_proc_create(kfs_lookup_path("parlib_draw_nanwan_standalone"));
                        proc_set_state(envs[0], PROC_RUNNABLE_S);
                        proc_run(envs[0]);
-                       schedule();
                        break;
 
                case 1:
                        envs[1] = kfs_proc_create(kfs_lookup_path("parlib_manycore_test"));
                        proc_set_state(envs[1], PROC_RUNNABLE_S);
                        proc_run(envs[1]);
-                       schedule();
                        break;
 
                case 2:
                        envs[2] = kfs_proc_create(kfs_lookup_path("parlib_draw_nanwan_standalone"));
                        proc_set_state(envs[2], PROC_RUNNABLE_S);
                        proc_run(envs[2]);
-                       schedule();
                        break;
 
                case 3:
@@ -227,9 +227,9 @@ void manager_waterman()
                        //envs[3] = kfs_proc_create(kfs_lookup_path("parlib_manycore_test"));
                        proc_set_state(envs[3], PROC_RUNNABLE_S);
                        proc_run(envs[3]);
-                       schedule();
                        break;
        }
+       schedule();
 
        panic("DON'T PANIC");
 }
index ed70f23..ed80e07 100644 (file)
@@ -306,7 +306,7 @@ void page_decref(page_t *page)
 static void __page_decref(page_t *page)
 {
        if (page->page_ref == 0) {
-               warn("Trying to Free already freed page: %d...\n", page2ppn(page));
+               panic("Trying to Free already freed page: %d...\n", page2ppn(page));
                return;
        }
        if (--page->page_ref == 0)
index 16bdae3..e90e6fe 100644 (file)
@@ -289,7 +289,7 @@ void* user_mem_check(env_t *env, const void *DANGEROUS va, size_t len, int perm)
                warn("Blimey!  Wrap around in VM range calculation!");  
                return NULL;
        }
-       num_pages = PPN(end - start);
+       num_pages = LA2PPN(end - start);
        for (i = 0; i < num_pages; i++, start += PGSIZE) {
                page_perms = get_va_perms(env->env_pgdir, start);
                // ensures the bits we want on are turned on.  if not, error out
@@ -419,7 +419,7 @@ error_t memcpy_from_user(env_t* env, void* COUNT(len) dest,
        if(start >= (void*SNT)ULIM || end >= (void*SNT)ULIM)
                return -EFAULT;
 
-       num_pages = PPN(end - start);
+       num_pages = LA2PPN(end - start);
        for(i = 0; i < num_pages; i++)
        {
                pte = pgdir_walk(env->env_pgdir, start+i*PGSIZE, 0);
@@ -474,7 +474,7 @@ error_t memcpy_to_user(env_t* env, void*DANGEROUS va,
        if(start >= (void*SNT)ULIM || end >= (void*SNT)ULIM)
                return -EFAULT;
 
-       num_pages = PPN(end - start);
+       num_pages = LA2PPN(end - start);
        for(i = 0; i < num_pages; i++)
        {
                pte = pgdir_walk(env->env_pgdir, start+i*PGSIZE, 0);
index 9df1878..b453d1d 100644 (file)
@@ -13,7 +13,7 @@
 void* sbrk(ptrdiff_t incr) 
 {
        debug_in_out("SBRK\n");
-       debug_in_out("\tincr: %u\n", incr);     
+       debug_in_out("\tincr: %d\n", incr);     
 
        extern char (SNT RO _end)[];
        static void* heap_end = NULL;