X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/0067bc210e621ccda286092d081a7890d65e1c18..db4d7d52fa00cc2fd3f25d971f57b73406d816ba:/lunaix-os/kernel/mm/pmm.c diff --git a/lunaix-os/kernel/mm/pmm.c b/lunaix-os/kernel/mm/pmm.c index 3bf2128..9c0d3eb 100644 --- a/lunaix-os/kernel/mm/pmm.c +++ b/lunaix-os/kernel/mm/pmm.c @@ -16,32 +16,27 @@ 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, + uint32_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 }; } } @@ -59,21 +54,18 @@ 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) - { + while (p2 < max_pg && p2 - p1 < num_pages) { (!(&pm_table[p2])->ref_counts) ? (p2++) : (p1 = p2); } @@ -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 - +int +pmm_ref_page(pid_t owner, void* page) +{ + (void*)owner; // TODO: do smth with owner + uint32_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) { +struct pp_struct* +pmm_query(void* pa) +{ uint32_t ppn = (uintptr_t)pa >> 12; - + if (ppn >= PM_BMP_MAX_SIZE) { return NULL; }