kernel/vm: Clean up virtual addr_range processing and rounding.

Only functional change should be the addition of alignment checks in
allocate_early_virtual.
This commit is contained in:
Augustin Cavalier
2024-10-14 15:06:12 -04:00
parent 16e96d6e04
commit 255bf69fbc
+36 -34
View File
@@ -4200,11 +4200,9 @@ create_preloaded_image_areas(struct preloaded_image* _image)
void void
vm_free_kernel_args(kernel_args* args) vm_free_kernel_args(kernel_args* args)
{ {
uint32 i;
TRACE(("vm_free_kernel_args()\n")); TRACE(("vm_free_kernel_args()\n"));
for (i = 0; i < args->num_kernel_args_ranges; i++) { for (uint32 i = 0; i < args->num_kernel_args_ranges; i++) {
area_id area = area_for((void*)(addr_t)args->kernel_args_range[i].start); area_id area = area_for((void*)(addr_t)args->kernel_args_range[i].start);
if (area >= B_OK) if (area >= B_OK)
delete_area(area); delete_area(area);
@@ -4218,11 +4216,11 @@ allocate_kernel_args(kernel_args* args)
TRACE(("allocate_kernel_args()\n")); TRACE(("allocate_kernel_args()\n"));
for (uint32 i = 0; i < args->num_kernel_args_ranges; i++) { for (uint32 i = 0; i < args->num_kernel_args_ranges; i++) {
void* address = (void*)(addr_t)args->kernel_args_range[i].start; const addr_range& range = args->virtual_allocated_range[i];
void* address = (void*)(addr_t)range.start;
create_area("_kernel args_", &address, B_EXACT_ADDRESS, create_area("_kernel args_", &address, B_EXACT_ADDRESS,
args->kernel_args_range[i].size, B_ALREADY_WIRED, range.size, B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
} }
} }
@@ -4233,9 +4231,9 @@ unreserve_boot_loader_ranges(kernel_args* args)
TRACE(("unreserve_boot_loader_ranges()\n")); TRACE(("unreserve_boot_loader_ranges()\n"));
for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) { for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) {
const addr_range& range = args->virtual_allocated_range[i];
vm_unreserve_address_range(VMAddressSpace::KernelID(), vm_unreserve_address_range(VMAddressSpace::KernelID(),
(void*)(addr_t)args->virtual_allocated_range[i].start, (void*)(addr_t)range.start, range.size);
args->virtual_allocated_range[i].size);
} }
} }
@@ -4246,18 +4244,19 @@ reserve_boot_loader_ranges(kernel_args* args)
TRACE(("reserve_boot_loader_ranges()\n")); TRACE(("reserve_boot_loader_ranges()\n"));
for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) { for (uint32 i = 0; i < args->num_virtual_allocated_ranges; i++) {
void* address = (void*)(addr_t)args->virtual_allocated_range[i].start; const addr_range& range = args->virtual_allocated_range[i];
void* address = (void*)(addr_t)range.start;
// If the address is no kernel address, we just skip it. The // If the address is no kernel address, we just skip it. The
// architecture specific code has to deal with it. // architecture specific code has to deal with it.
if (!IS_KERNEL_ADDRESS(address)) { if (!IS_KERNEL_ADDRESS(address)) {
dprintf("reserve_boot_loader_ranges(): Skipping range: %p, %" dprintf("reserve_boot_loader_ranges(): Skipping range: %p, %"
B_PRIu64 "\n", address, args->virtual_allocated_range[i].size); B_PRIu64 "\n", address, range.size);
continue; continue;
} }
status_t status = vm_reserve_address_range(VMAddressSpace::KernelID(), status_t status = vm_reserve_address_range(VMAddressSpace::KernelID(),
&address, B_EXACT_ADDRESS, args->virtual_allocated_range[i].size, 0); &address, B_EXACT_ADDRESS, range.size, 0);
if (status < B_OK) if (status < B_OK)
panic("could not reserve boot loader ranges\n"); panic("could not reserve boot loader ranges\n");
} }
@@ -4268,48 +4267,51 @@ static addr_t
allocate_early_virtual(kernel_args* args, size_t size, addr_t alignment) allocate_early_virtual(kernel_args* args, size_t size, addr_t alignment)
{ {
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
if (alignment <= B_PAGE_SIZE) {
// All allocations are naturally page-aligned.
alignment = 0;
} else {
ASSERT((alignment % B_PAGE_SIZE) == 0);
}
// find a slot in the virtual allocation addr range // Find a slot in the virtual allocation ranges.
for (uint32 i = 1; i < args->num_virtual_allocated_ranges; i++) { for (uint32 i = 1; i < args->num_virtual_allocated_ranges; i++) {
// check to see if the space between this one and the last is big enough // Check if the space between this one and the previous is big enough.
addr_t rangeStart = args->virtual_allocated_range[i].start; const addr_range& range = args->virtual_allocated_range[i];
addr_t previousRangeEnd = args->virtual_allocated_range[i - 1].start addr_range& previousRange = args->virtual_allocated_range[i - 1];
+ args->virtual_allocated_range[i - 1].size; const addr_t previousRangeEnd = previousRange.start + previousRange.size;
addr_t base = alignment > 0 addr_t base = alignment > 0
? ROUNDUP(previousRangeEnd, alignment) : previousRangeEnd; ? ROUNDUP(previousRangeEnd, alignment) : previousRangeEnd;
if (base >= KERNEL_BASE && base < rangeStart if (base >= KERNEL_BASE && base < range.start && (range.start - base) >= size) {
&& rangeStart - base >= size) { previousRange.size += base + size - previousRangeEnd;
args->virtual_allocated_range[i - 1].size
+= base + size - previousRangeEnd;
return base; return base;
} }
} }
// we hadn't found one between allocation ranges. this is ok. // We didn't find one between allocation ranges. This is OK.
// see if there's a gap after the last one // See if there's a gap after the last one.
int lastEntryIndex = args->num_virtual_allocated_ranges - 1; addr_range& lastRange
addr_t lastRangeEnd = args->virtual_allocated_range[lastEntryIndex].start = args->virtual_allocated_range[args->num_virtual_allocated_ranges - 1];
+ args->virtual_allocated_range[lastEntryIndex].size; const addr_t lastRangeEnd = lastRange.start + lastRange.size;
addr_t base = alignment > 0 addr_t base = alignment > 0
? ROUNDUP(lastRangeEnd, alignment) : lastRangeEnd; ? ROUNDUP(lastRangeEnd, alignment) : lastRangeEnd;
if (KERNEL_BASE + (KERNEL_SIZE - 1) - base >= size) { if (KERNEL_BASE + (KERNEL_SIZE - 1) - base >= size) {
args->virtual_allocated_range[lastEntryIndex].size lastRange.size += base + size - lastRangeEnd;
+= base + size - lastRangeEnd;
return base; return base;
} }
// see if there's a gap before the first one // See if there's a gap before the first one.
addr_t rangeStart = args->virtual_allocated_range[0].start; addr_range& firstRange = args->virtual_allocated_range[0];
if (rangeStart > KERNEL_BASE && rangeStart - KERNEL_BASE >= size) { if (firstRange.start > KERNEL_BASE && (firstRange.start - KERNEL_BASE) >= size) {
base = rangeStart - size; base = firstRange.start - size;
if (alignment > 0) if (alignment > 0)
base = ROUNDDOWN(base, alignment); base = ROUNDDOWN(base, alignment);
if (base >= KERNEL_BASE) { if (base >= KERNEL_BASE) {
args->virtual_allocated_range[0].start = base; firstRange.start = base;
args->virtual_allocated_range[0].size += rangeStart - base; firstRange.size += firstRange.start - base;
return base; return base;
} }
} }
@@ -4431,7 +4433,7 @@ vm_allocate_early(kernel_args* args, size_t virtualSize, size_t physicalSize,
} }
// map the pages // map the pages
for (uint32 i = 0; i < PAGE_ALIGN(physicalSize) / B_PAGE_SIZE; i++) { for (uint32 i = 0; i < HOWMANY(physicalSize, B_PAGE_SIZE); i++) {
page_num_t physicalAddress = vm_allocate_early_physical_page(args); page_num_t physicalAddress = vm_allocate_early_physical_page(args);
if (physicalAddress == 0) if (physicalAddress == 0)
panic("error allocating early page!\n"); panic("error allocating early page!\n");