From cd430b6fe5a6e67e174ebb1111b6473d0842db31 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 10 Oct 2024 00:44:27 -0400 Subject: [PATCH] kernel/vm: Also try starting new ranges in vm_allocate_early_physical_page. If the existing allocated ranges are from physical memory ranges that are just too small, then we'll need to start a new "allocated" range based on the next-available physical memory range. Should fix the "PANIC: error allocating early page!" tickets (i.e. #14659 and friends.) --- src/system/kernel/vm/vm.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index 009c698a46..ad24c086a8 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -4325,8 +4325,8 @@ is_page_in_physical_memory_range(kernel_args* args, phys_addr_t address) // allocated for (uint32 i = 0; i < args->num_physical_memory_ranges; i++) { if (address >= args->physical_memory_range[i].start - && address < args->physical_memory_range[i].start - + args->physical_memory_range[i].size) + && address < (args->physical_memory_range[i].start + + args->physical_memory_range[i].size)) return true; } return false; @@ -4379,6 +4379,32 @@ vm_allocate_early_physical_page(kernel_args* args) } } + // Try starting a new range. + if (args->num_physical_allocated_ranges < MAX_PHYSICAL_ALLOCATED_RANGE) { + const uint32 next = args->num_physical_allocated_ranges; + phys_addr_t lastPage = args->physical_allocated_range[next - 1].start + + args->physical_allocated_range[next - 1].size; + + phys_addr_t nextPage = 0; + for (uint32 i = 0; i < args->num_physical_memory_ranges; i++) { + // Ignore everything before the last-allocated page, as well as small ranges. + if (args->physical_memory_range[i].start < lastPage) + continue; + if (args->physical_memory_range[i].size < (B_PAGE_SIZE * 128)) + continue; + + nextPage = args->physical_memory_range[i].start; + } + + if (nextPage != 0) { + // we got one! + args->num_physical_allocated_ranges++; + args->physical_allocated_range[next].start = nextPage; + args->physical_allocated_range[next].size = B_PAGE_SIZE; + return nextPage / B_PAGE_SIZE; + } + } + return 0; // could not allocate a block }