forked from Bananymous/banan-os
Kernel: VirtualRange creation can fail
This commit is contained in:
parent
c0c0bbc1bf
commit
88e3998664
|
@ -1,3 +1,4 @@
|
||||||
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <kernel/Memory/Heap.h>
|
#include <kernel/Memory/Heap.h>
|
||||||
#include <kernel/Memory/VirtualRange.h>
|
#include <kernel/Memory/VirtualRange.h>
|
||||||
|
|
||||||
|
@ -9,35 +10,49 @@ namespace Kernel
|
||||||
ASSERT(size % PAGE_SIZE == 0);
|
ASSERT(size % PAGE_SIZE == 0);
|
||||||
ASSERT(vaddr % PAGE_SIZE == 0);
|
ASSERT(vaddr % PAGE_SIZE == 0);
|
||||||
|
|
||||||
VirtualRange* result = new VirtualRange(page_table);
|
VirtualRange* result_ptr = new VirtualRange(page_table);
|
||||||
ASSERT(result);
|
if (result_ptr == nullptr)
|
||||||
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
|
auto result = BAN::UniqPtr<VirtualRange>::adopt(result_ptr);
|
||||||
|
|
||||||
result->m_kmalloc = false;
|
result->m_kmalloc = false;
|
||||||
result->m_size = size;
|
result->m_size = size;
|
||||||
result->m_flags = flags;
|
result->m_flags = flags;
|
||||||
MUST(result->m_physical_pages.reserve(size / PAGE_SIZE));
|
TRY(result->m_physical_pages.reserve(size / PAGE_SIZE));
|
||||||
|
|
||||||
page_table.lock();
|
page_table.lock();
|
||||||
|
|
||||||
if (vaddr == 0)
|
if (vaddr == 0)
|
||||||
{
|
{
|
||||||
vaddr = page_table.get_free_contiguous_pages(size / PAGE_SIZE, 0x300000);
|
vaddr = page_table.get_free_contiguous_pages(size / PAGE_SIZE, 0x300000);
|
||||||
ASSERT(vaddr);
|
if (vaddr == 0)
|
||||||
|
{
|
||||||
|
derrorln("out of virtual memory");
|
||||||
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result->m_vaddr = vaddr;
|
result->m_vaddr = vaddr;
|
||||||
|
|
||||||
ASSERT(page_table.is_range_free(vaddr, size));
|
ASSERT(page_table.is_range_free(vaddr, size));
|
||||||
|
|
||||||
|
TRY(result->m_physical_pages.reserve(size / PAGE_SIZE));
|
||||||
for (size_t offset = 0; offset < size; offset += PAGE_SIZE)
|
for (size_t offset = 0; offset < size; offset += PAGE_SIZE)
|
||||||
{
|
{
|
||||||
paddr_t paddr = Heap::get().take_free_page();
|
paddr_t paddr = Heap::get().take_free_page();
|
||||||
ASSERT(paddr);
|
if (paddr == 0)
|
||||||
|
{
|
||||||
|
for (paddr_t release : result->m_physical_pages)
|
||||||
|
Heap::get().release_page(release);
|
||||||
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
|
}
|
||||||
MUST(result->m_physical_pages.push_back(paddr));
|
MUST(result->m_physical_pages.push_back(paddr));
|
||||||
page_table.map_page_at(paddr, vaddr + offset, flags);
|
page_table.map_page_at(paddr, vaddr + offset, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
page_table.unlock();
|
page_table.unlock();
|
||||||
|
|
||||||
return BAN::UniqPtr<VirtualRange>::adopt(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::UniqPtr<VirtualRange>> VirtualRange::create_kmalloc(size_t size)
|
BAN::ErrorOr<BAN::UniqPtr<VirtualRange>> VirtualRange::create_kmalloc(size_t size)
|
||||||
|
@ -52,7 +67,7 @@ namespace Kernel
|
||||||
if (result->m_vaddr == 0)
|
if (result->m_vaddr == 0)
|
||||||
{
|
{
|
||||||
delete result;
|
delete result;
|
||||||
return BAN::UniqPtr<VirtualRange>();
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
return BAN::UniqPtr<VirtualRange>::adopt(result);
|
return BAN::UniqPtr<VirtualRange>::adopt(result);
|
||||||
|
|
Loading…
Reference in New Issue