[kernel] Add vm_space::allocate
Refactored out vm_space::handle_fault's allocation code into a separate vm_space::allocate function, and reimplemented handle_fault in terms of the new function.
This commit is contained in:
@@ -256,31 +256,40 @@ vm_space::initialize_tcb(TCB &tcb)
|
|||||||
~memory::page_offset;
|
~memory::page_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
vm_space::allocate(uintptr_t virt, size_t count, uintptr_t *phys)
|
||||||
|
{
|
||||||
|
uintptr_t base = 0;
|
||||||
|
vm_area *area = get(virt, &base);
|
||||||
|
|
||||||
|
uintptr_t offset = (virt & ~0xfffull) - base;
|
||||||
|
if (!area || !area->allowed(offset))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uintptr_t addr = 0;
|
||||||
|
size_t n = frame_allocator::get().allocate(count, &addr);
|
||||||
|
|
||||||
|
void *mem = memory::to_virtual<void>(addr);
|
||||||
|
if (area->flags() && vm_flags::zero)
|
||||||
|
kutil::memset(mem, 0, count * memory::frame_size);
|
||||||
|
|
||||||
|
area->commit(addr, offset, 1);
|
||||||
|
if (phys)
|
||||||
|
*phys = addr;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
vm_space::handle_fault(uintptr_t addr, fault_type fault)
|
vm_space::handle_fault(uintptr_t addr, fault_type fault)
|
||||||
{
|
{
|
||||||
uintptr_t page = addr & ~0xfffull;
|
|
||||||
|
|
||||||
// TODO: Handle more fult types
|
// TODO: Handle more fult types
|
||||||
if (fault && fault_type::present)
|
if (fault && fault_type::present)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uintptr_t base = 0;
|
size_t n = allocate(addr, 1, nullptr);
|
||||||
vm_area *area = get(addr, &base);
|
|
||||||
|
|
||||||
if (!area || !area->allowed(page-base))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uintptr_t phys = 0;
|
|
||||||
size_t n = frame_allocator::get().allocate(1, &phys);
|
|
||||||
kassert(n, "Failed to allocate a new page during page fault");
|
kassert(n, "Failed to allocate a new page during page fault");
|
||||||
|
return n;
|
||||||
if (area->flags() && vm_flags::zero)
|
|
||||||
kutil::memset(memory::to_virtual<void>(phys), 0, memory::frame_size);
|
|
||||||
|
|
||||||
uintptr_t offset = page - base;
|
|
||||||
area->commit(phys, offset, 1);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
|||||||
@@ -79,6 +79,13 @@ public:
|
|||||||
fetch = 0x10
|
fetch = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Allocate pages into virtual memory. May allocate less than requested.
|
||||||
|
/// \arg virt The virtual address at which to allocate
|
||||||
|
/// \arg count The number of pages to allocate
|
||||||
|
/// \arg phys [out] The physical address of the pages allocated
|
||||||
|
/// \returns The number of pages actually allocated
|
||||||
|
size_t allocate(uintptr_t virt, size_t count, uintptr_t *phys);
|
||||||
|
|
||||||
/// Handle a page fault.
|
/// Handle a page fault.
|
||||||
/// \arg addr Address which caused the fault
|
/// \arg addr Address which caused the fault
|
||||||
/// \arg ft Flags from the interrupt about the kind of fault
|
/// \arg ft Flags from the interrupt about the kind of fault
|
||||||
|
|||||||
Reference in New Issue
Block a user