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.)
This commit is contained in:
Augustin Cavalier 2024-10-10 00:44:27 -04:00
parent 27d0a861e0
commit cd430b6fe5

View File

@ -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
}