regression: elf loading
[lunaix-os.git] / lunaix-os / kernel / mm / pmm.c
index 3bf2128969fcf4129065c2e50378abe80d3e85f9..3ebe22a10d34fdcec5446283534a1e10e4ca0051 100644 (file)
@@ -16,39 +16,34 @@ pmm_mark_page_free(uintptr_t ppn)
 void
 pmm_mark_page_occupied(pid_t owner, uintptr_t ppn, pp_attr_t attr)
 {
-    pm_table[ppn] = (struct pp_struct) {
-        .owner = owner,
-        .ref_counts = 1,
-        .attr = attr
-    };
+    pm_table[ppn] =
+      (struct pp_struct){ .owner = owner, .ref_counts = 1, .attr = attr };
 }
 
 void
 pmm_mark_chunk_free(uintptr_t start_ppn, size_t page_count)
 {
-    for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++)
-    {
+    for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) {
         pm_table[i].ref_counts = 0;
     }
 }
 
 void
-pmm_mark_chunk_occupied(pid_t owner, uint32_t start_ppn, size_t page_count, pp_attr_t attr)
+pmm_mark_chunk_occupied(pid_t owner,
+                        u32_t start_ppn,
+                        size_t page_count,
+                        pp_attr_t attr)
 {
-    for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++)
-    {
-        pm_table[i] = (struct pp_struct) {
-            .owner = owner,
-            .ref_counts = 1,
-            .attr = attr
-        };
+    for (size_t i = start_ppn; i < start_ppn + page_count && i < max_pg; i++) {
+        pm_table[i] =
+          (struct pp_struct){ .owner = owner, .ref_counts = 1, .attr = attr };
     }
 }
 
 // 我们跳过位于0x0的页。我们不希望空指针是指向一个有效的内存空间。
 #define LOOKUP_START 1
 
-size_t pg_lookup_ptr;
+volatile size_t pg_lookup_ptr;
 
 void
 pmm_init(uintptr_t mem_upper_lim)
@@ -59,25 +54,22 @@ pmm_init(uintptr_t mem_upper_lim)
 
     // mark all as occupied
     for (size_t i = 0; i < PM_BMP_MAX_SIZE; i++) {
-        pm_table[i] = (struct pp_struct) {
-            .owner = 0,
-            .attr = 0,
-            .ref_counts = 1
-        };
+        pm_table[i] =
+          (struct pp_struct){ .owner = 0, .attr = 0, .ref_counts = 1 };
     }
 }
 
 void*
-pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr) {
+pmm_alloc_cpage(pid_t owner, size_t num_pages, pp_attr_t attr)
+{
     size_t p1 = 0;
     size_t p2 = 0;
 
-    while (p2 < max_pg && p2 - p1 < num_pages)
-    {
-        (!(&pm_table[p2])->ref_counts) ? (p2++) : (p1 = p2);
+    while (p2 < max_pg && p2 - p1 < num_pages) {
+        (!(&pm_table[p2])->ref_counts) ? (p2++) : (p1 = ++p2);
     }
 
-    if (p2 < max_pg) {
+    if (p2 == max_pg && p2 - p1 < num_pages) {
         return NULL;
     }
 
@@ -97,14 +89,12 @@ pmm_alloc_page(pid_t owner, pp_attr_t attr)
     while (!good_page_found && pg_lookup_ptr < upper_lim) {
         pm = &pm_table[pg_lookup_ptr];
 
-        // skip the fully occupied chunk, reduce # of iterations
         if (!pm->ref_counts) {
-            *pm = (struct pp_struct) {
-                .attr = attr,
-                .owner = owner,
-                .ref_counts = 1
-            };
+            *pm = (struct pp_struct){ .attr = attr,
+                                      .owner = owner,
+                                      .ref_counts = 1 };
             good_page_found = pg_lookup_ptr << 12;
+            break;
         } else {
             pg_lookup_ptr++;
 
@@ -128,28 +118,36 @@ int
 pmm_free_page(pid_t owner, void* page)
 {
     struct pp_struct* pm = &pm_table[(intptr_t)page >> 12];
-    
-    // Oops, double free!
-    if (!(pm->ref_counts)) {
+
+    // Is this a MMIO mapping or double free?
+    if (((intptr_t)page >> 12) >= max_pg || !(pm->ref_counts)) {
+        return 0;
+    }
+
+    // 如果是锁定页,则不作处理
+    if ((pm->attr & PP_FGLOCKED)) {
         return 0;
     }
 
-    // TODO: 检查权限,保证:1) 只有正在使用该页(包括被分享者)的进程可以释放; 2) 内核可释放所有页。
+    // TODO: 检查权限,保证:1) 只有正在使用该页(包括被分享者)的进程可以释放;
+    // 2) 内核可释放所有页。
     pm->ref_counts--;
     return 1;
 }
 
-int pmm_ref_page(pid_t owner, void* page) {
-    (void*) owner;      // TODO: do smth with owner
-    
-    uint32_t ppn = (uintptr_t)page >> 12;
-    
+int
+pmm_ref_page(pid_t owner, void* page)
+{
+    (void*)owner; // TODO: do smth with owner
+
+    u32_t ppn = (uintptr_t)page >> 12;
+
     if (ppn >= PM_BMP_MAX_SIZE) {
         return 0;
     }
 
     struct pp_struct* pm = &pm_table[ppn];
-    if (!pm->ref_counts) {
+    if (ppn >= max_pg || !pm->ref_counts) {
         return 0;
     }
 
@@ -157,9 +155,11 @@ int pmm_ref_page(pid_t owner, void* page) {
     return 1;
 }
 
-struct pp_struct* pmm_query(void* pa) {
-    uint32_t ppn = (uintptr_t)pa >> 12;
-    
+struct pp_struct*
+pmm_query(void* pa)
+{
+    u32_t ppn = (uintptr_t)pa >> 12;
+
     if (ppn >= PM_BMP_MAX_SIZE) {
         return NULL;
     }