[kernel] Fix frame allocation for multiple pages

There was an inverted boolean logic in determining how many consecutive
pages were available.

Also adding some memory debugging tools I added to track down the recent
memory bugs:

- A direct debugcon::write call, for logging to the debugcon without the
  possible page faults with the logger.
- A new vm_space::lock call, to make a page not fillable in memory
  debugging mode
- A mode in heap_allocator to always alloc new pages, and lock freed
  pages to cause page faults for use-after-free bugs.
- Logging in kobject on creation and deletion
- Page table cache structs are now page-sized for easy pointer math
This commit is contained in:
Justin C. Miller
2023-02-19 01:07:13 -08:00
parent 55c88dd943
commit d2a6113fb7
11 changed files with 131 additions and 20 deletions

View File

@@ -8,6 +8,8 @@
#include "assert.h"
#include "heap_allocator.h"
#include "memory.h"
#include "objects/vm_area.h"
#include "vm_space.h"
uint32_t & get_map_key(heap_allocator::block_info &info) { return info.offset; }
@@ -46,7 +48,6 @@ heap_allocator::heap_allocator(uintptr_t start, size_t size, uintptr_t heapmap)
m_maxsize {size},
m_allocated_size {0},
m_map (reinterpret_cast<block_info*>(heapmap), 512)
{
memset(m_free, 0, sizeof(m_free));
}
@@ -57,6 +58,11 @@ heap_allocator::allocate(size_t length)
if (length == 0)
return nullptr;
static constexpr unsigned min_order =
__debug_heap_allocation ?
12 : // allocating full pages in debug mode
heap_allocator::min_order;
unsigned order = util::log2(length);
if (order < min_order)
order = min_order;
@@ -98,6 +104,15 @@ heap_allocator::free(void *p)
size_t size = (1ull << info->order);
m_allocated_size -= size;
if constexpr (__debug_heap_allocation) {
extern obj::vm_area_untracked &g_kernel_heap_area;
size_t offset = reinterpret_cast<uintptr_t>(p) - mem::heap_offset;
size_t pages = mem::bytes_to_pages(size);
vm_space::kernel_space().lock(g_kernel_heap_area, offset, pages);
return;
}
block->clear(info->order);
block = merge_block(block);
register_free_block(block, block->order);