]> git.corax.cc Git - corax/commitdiff
Make _pg_dir_map_legacy() map large pages, where possible
authorMatthias Kruk <m@m10k.eu>
Tue, 17 Sep 2019 07:48:40 +0000 (16:48 +0900)
committerMatthias Kruk <m@m10k.eu>
Tue, 17 Sep 2019 07:48:40 +0000 (16:48 +0900)
kernel/arch/paging.c

index 5277d105b4d4ee63247d082abf1002c57b544e94..7991817df7e44a1da51d3c2032c6a6f67f8724b9 100644 (file)
@@ -355,17 +355,32 @@ static int _pg_dir_map_legacy(page_table_t *pd, u32_t paddr, u32_t vaddr, u32_t
 
                /* allocate a new page table if not present */
                if(!(pd->pt_entries[pde] & PAGE_ATTR_PRESENT)) {
-                       pd->pt_entries[pde] = (u32_t)pg_frame_alloc_end();
+                       /*
+                        * Allocate a large page if we're at a large page boundary
+                        * and we're supposed to allocate at least the size of a large page
+                        */
+                       if(size >= PAGE_SIZE_LARGE && ALIGNED(vaddr, PAGE_SIZE_LARGE)) {
+                               pd->pt_entries[pde] = vaddr | PAGE_ATTR_SIZE | PAGE_ATTR_PRESENT | flags;
 
-                       if(!pd->pt_entries[pde]) {
-                               ret_val = -ENOMEM;
-                               break;
+                               paddr += PAGE_SIZE_LARGE;
+                               vaddr += PAGE_SIZE_LARGE;
+                               size -= PAGE_SIZE_LARGE;
+
+                               /* skip the rest of the loop, which would attempt to populate the page table */
+                               continue;
                        } else {
-                               /* wipe the page table before using it */
-                               memset((void*)pd->pt_entries[pde], 0, PAGE_SIZE);
-                       }
+                               pd->pt_entries[pde] = (u32_t)pg_frame_alloc_end();
+
+                               if(!pd->pt_entries[pde]) {
+                                       ret_val = -ENOMEM;
+                                       break;
+                               } else {
+                                       /* wipe the page table before using it */
+                                       memset((void*)pd->pt_entries[pde], 0, PAGE_SIZE);
+                               }
 
-                       pd->pt_entries[pde] |= PAGE_ATTR_PRESENT | flags;
+                               pd->pt_entries[pde] |= PAGE_ATTR_PRESENT | flags;
+                       }
                }
 
                pt = (page_table_t*)(pd->pt_entries[pde] & 0xfffff000);